Pushed Authorization Request (PAR)
Pushed Authorization Request (PAR) is defined in RFC 9126. It allows a client to push its authorization parameters directly to the authorization server — before redirecting the user — receiving back a short-lived request_uri reference. This eliminates sensitive parameters from the browser URL and enables richer payloads such as authorization_details (RFC 9396) to be transmitted securely over a back-channel.
Key Concepts
| Concept | Description |
|---|---|
request_uri | Opaque reference (urn:ietf:params:oauth:request_uri:<token>) returned by the PAR endpoint. Valid for 90 seconds by default. |
authorization_details | Structured JSON object (RFC 9396) describing the authorization context — e.g. payment amount, payee, currency. Passed by the client at PAR time and propagated through the entire flow into the final JWT. |
linking_id | Server-generated UUID created during PAR for SCA flows. Correlates the browser session with the mobile MFA device. See Step-Up Authentication for details. |
Enable PAR in the Admin Console
In the Admin Console, navigate to Applications → select your OIDC app → Tokens tab → Authorization Requests section.
- Toggle Pushed Authorization Request (PAR) ON.
- Optionally enable Require PAR to force all authorization requests through the PAR endpoint.
Only enable Require PAR on a dedicated app. Any /authorize call without a request_uri will be rejected. Create a separate app for PAR flows and leave standard login apps unchanged.
To attach authorization_details to PAR requests, also enable Rich Authorization Request (RAR):
- Toggle Rich Authorization Request (RAR) ON.
- Under Allowed RAR Types, click + Add Type and enter your type string (e.g.
lr_payment). This value must match thetypefield inauthorization_details. Matching is case-insensitive.
Step 1 — Push Authorization Request
The client makes a back-channel POST to the PAR endpoint with all authorization parameters.
Endpoint
POST https://{SiteURL}/api/oidc/{OIDCAppName}/par
Request
POST /api/oidc/MyApp/par
Content-Type: application/x-www-form-urlencoded
client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
&response_type=code
&scope=openid profile
&redirect_uri=https://your-app.com/callback
&authorization_details=[{"type":"lr_payment","amount":"500","currency":"EUR","payee":"Stripe"}]
Response
{
"request_uri": "urn:ietf:params:oauth:request_uri:abc123xyz",
"expires_in": 90
}
PAR Request Parameters
| Parameter | Required | Description |
|---|---|---|
client_id | ✅ Required | Your OIDC application client ID |
client_secret | ✅ Required | Your OIDC application client secret |
response_type | ✅ Required | Must be code |
scope | ✅ Required | Space-delimited scopes. Must include openid. |
redirect_uri | ✅ Required | Callback URL. Must be whitelisted in Admin Console. |
authorization_details | Optional | JSON array (RFC 9396) describing the authorization context. Propagated into the final JWT authorization_details claim. |
nonce | Optional | Replay attack prevention for id_token. |
code_challenge | Optional | PKCE code challenge. |
code_challenge_method | Optional | PKCE method. Must be S256. |
workflow | Optional | Name of the IO Workflow to invoke (required for SCA flows). |
Step 2 — Authorization Request with request_uri
The client redirects the user's browser to /authorize using the request_uri reference. No sensitive parameters appear in the URL.
Endpoint
GET https://{SiteURL}/service/oidc/{OIDCAppName}/authorize
Example Request
GET https://your-app.hub.loginradius.com/service/oidc/MyApp/authorize
?request_uri=urn:ietf:params:oauth:request_uri:abc123xyz
&client_id=YOUR_CLIENT_ID
What happens:
- LoginRadius resolves the
request_uriand retrieves your authorization parameters from its cache. - All parameters you submitted — including
authorization_detailsandlinking_idif present — are restored. - LoginRadius bundles these into a short-lived, signed session token and redirects the user to begin the authorization flow.
Step 3 — Token Exchange
After the workflow completes and the client receives an authorization_code, it exchanges it for tokens. Any authorization_details from the PAR request are included as a claim in the returned JWT.
Endpoint
POST https://{SiteURL}/api/oidc/{OIDCAppName}/token
Success Response
{
"access_token": "<JWT>",
"token_type": "Bearer",
"expires_in": 3600,
"id_token": "<JWT with authorization_details claim>",
"refresh_token": "<refresh-token>"
}
Decoded id_token payload (example)
{
"sub": "user-uid",
"iss": "https://your-app.hub.loginradius.com/",
"aud": "YOUR_CLIENT_ID",
"iat": 1714000000,
"exp": 1714003600,
"authorization_details": {
"type": "lr_payment",
"amount": "500",
"currency": "EUR",
"payee": "Stripe"
},
"linking_id": "<linking_id>"
}
Differences from Standard Authorization Code Flow
| Aspect | Standard Auth Code Flow | PAR Flow |
|---|---|---|
| Authorization params location | Browser URL (query string) | Back-channel POST to /par |
authorization_details support | Not available | Available via RFC 9396 |
| Sensitive params exposure | Visible in browser history / server logs | Never reach the browser |
request_uri | Not used | Short-lived opaque reference (90s) |