Skip to content
Version v3.2.0

Pushed and JWT-Secured Authorization Requests ​

ProAuth supports Pushed Authorization Requests (PAR, RFC 9126) and JWT-Secured Authorization Requests (JAR, RFC 9101) for clients that need a hardened authorization request flow.

FAPI 2.0 clients must use PAR for every authorization request. See FAPI 2.0 Security Profile.

PAR lets a client POST the authorization request to ProAuth before redirecting the browser. ProAuth returns a one-time request_uri, keeping sensitive request parameters out of the front channel and avoiding URL length limits. JAR lets a client sign the authorization request as a JWT so ProAuth can validate request integrity before continuing the authorization flow.

Discovery Metadata ​

Tenant discovery advertises the PAR and JAR capabilities:

json
{
  "pushed_authorization_request_endpoint": "https://idp.example.com/{tenant}/connect/par",
  "request_parameter_supported": true,
  "request_uri_parameter_supported": true,
  "require_request_uri_registration": true,
  "request_object_signing_alg_values_supported": ["RS256", "PS256", "ES256"],
  "request_object_encryption_alg_values_supported": ["RSA-OAEP"],
  "request_object_encryption_enc_values_supported": ["A256GCM"]
}

require_pushed_authorization_requests is included only when tenant-level PAR enforcement is enabled.

Tenant Configuration ​

Configure these tenant options:

OptionDefaultDescription
PushedAuthorizationRequestLifetime00:01:30Lifetime of a pushed request URI.
RequirePushedAuthorizationRequestsfalseRequires PAR for clients that inherit tenant policy.
ParRequestFetchTimeoutInSeconds5Timeout when fetching registered remote request_uri request objects.
ParRequestFetchMaxBytes102400Maximum response size when fetching registered remote request_uri request objects.
AllowPrivateNetworkRequestUrisfalseAllows registered remote request_uri request objects to resolve to private network addresses. Keep disabled unless the tenant explicitly trusts that network and the host is not controlled by untrusted clients.

Client Configuration ​

Client applications expose these v2 Management API and AdminApp fields:

FieldDescription
RequirePushedAuthorizationRequestsNullable override. null inherits tenant policy, true requires PAR, false allows direct authorization requests.
RequestObjectSigningAlgOptional required JAR signing algorithm for the client.
RequestObjectEncryptionAlgOptional JWE key-management algorithm.
RequestObjectEncryptionEncOptional JWE content-encryption method.
Client App Key SetsOne or more key sets with usage RequestObjectSigning; ProAuth uses these keys to validate signed request objects.
Allowed Request URIsExact HTTPS allowlist for remote JAR request_uri values.

Signed request objects must use asymmetric RS*, PS*, or ES* algorithms. none and HMAC signing algorithms are not accepted.

In the AdminApp, open Client Apps → Security → Signed and encrypted requests. The request signing selector offers RSA, RSA-PSS and ECDSA choices. Any supported asymmetric algorithm leaves the client-specific restriction unset; a valid signature from a registered client key is still required. Encryption selectors record metadata. Not configured leaves that metadata unset; these fields do not enforce a per-client request-encryption policy. Check the provider's discovery document and configured keys for available encryption algorithms.

Allowed Request URIs are saved independently of the client form. Save request URI commits the URI immediately; cancelling the parent client configuration does not undo it.

For ProAuth v3 configurations, store request-object signing keys in ClientAppKeySet records with usage RequestObjectSigning. Public request-object keys are no longer configured directly on the client application. See Client App Key Sets.

Public clients must send code_challenge with code_challenge_method=S256 for authorization-code flows, including PAR and hybrid responses containing a code. Requests that omit it or use plain are rejected with invalid_request before a code is issued. PKCE binds an authorization code to its initiating client instance. Confidential clients must still authenticate at the token endpoint when presenting code_verifier; missing required client authentication returns invalid_client.

PAR Flow ​

  1. The client authenticates to POST /connect/par or POST /{tenantKey}/connect/par using the same client authentication style as the token endpoint: client_secret_basic, client_secret_post, client_secret_jwt, private_key_jwt, tls_client_auth, self_signed_tls_client_auth, or a registered public-client client_id when public clients are allowed.
  2. The client sends normal authorization request parameters as form fields, for example client_id, response_type, scope, redirect_uri, state, nonce, code_challenge, and code_challenge_method.
  3. ProAuth validates and stores the pushed request and returns 201 Created:
json
{
  "request_uri": "urn:ietf:params:oauth:request_uri:<opaque-reference>",
  "expires_in": 90
}
  1. The client redirects the browser to the authorization endpoint with client_id and the returned request_uri.
  2. ProAuth resolves the pushed request server-side, keeping its authenticated parameters authoritative through login and consent. Visiting the login page does not consume the request URI. Acceptance or rejection consumes it; expired or already consumed PAR URNs fail with invalid_request_uri. Consumption is protected by optimistic concurrency so concurrent browser retries cannot redeem the same pushed request more than once.

A pushed request with prompt=login or max_age=0 requires fresh authentication. After login and MFA complete, ProAuth resumes that same authorization without repeating the login challenge. A new authorization request requires fresh authentication again. The max_age parameter remains available for issuance of the required auth_time claim.

The response includes Cache-Control: no-store and Pragma: no-cache.

ProAuth.Oidc.Client exposes PAR directly through IOidcClient.PushAuthorizationRequestAsync(AuthRequest). The method discovers pushed_authorization_request_endpoint, applies the configured AuthenticationSettings.ClientAuthenticationMethod, posts the authorization request as form fields, and returns the request_uri and expiry from ProAuth.

The ProAuth.Bff package uses ASP.NET Core's built-in PAR support and applies the configured client authentication method during the PAR call. Configure AuthenticationSettings:PushedAuthorizationBehavior with UseIfAvailable, Disable, or Require.

JAR Flow ​

Inline JAR uses the request authorization parameter. Remote JAR uses request_uri; the URI must be registered exactly for the client.

Request-object claims must not conflict with query or form parameters. Duplicate parameters are accepted only when the values are identical; otherwise ProAuth rejects the request with invalid_request_object. client_id must match the authenticated or outer client. ProAuth validates iss, aud, exp, signature, and the configured client signing metadata before continuing.

Remote request-object fetching uses SSRF controls: HTTPS only, no userinfo, no fragment, exact per-client allowlist, no redirects, short timeout, response-size cap, DNS resolution before fetch, and private or loopback host blocking unless explicit tenant configuration allows it. Remote key sets used to validate request-object signatures are stricter: they are always HTTPS-only, no userinfo, no fragment, and public-address only.

Encrypted request objects are accepted only when they decrypt to a signed JWT using ProAuth encryption keys.

ProAuth.Bff can sign authorization requests as inline request objects. Set AuthenticationSettings:RequestObject:Enabled to true and provide a base64 PFX signing certificate. The corresponding public key must be registered as a client app key set with usage RequestObjectSigning, and RequestObjectSigningAlg must match the configured signing algorithm when set.