Implement Pushed Authorization Requests #292
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
PAR + PKCE Behavior Summary
This PR extends the Generic OAuth2 Capacitor plugin to support Pushed Authorization Requests (PAR) on all platforms (Web, Android, iOS) while keeping the existing API backward compatible.
New configuration
OAuth2AuthenticateBaseOptions.parEndpoint?: stringpushed_authorization_request_endpoint).web.parEndpoint,android.parEndpoint, orios.parEndpoint.Behavior:
parEndpointis unset for a platform:parEndpointis set for a platform:request_uriwhen starting the authorization flow.Single PKCE verifier per auth attempt
Across all platforms the plugin now guarantees that:
pkceEnabledistrue, a single PKCE code verifier is generated for the auth attempt.Platform details:
Web
WebUtils.buildWebOptions:pkceCodeVerifieronce (or reuses it fromsessionStorage).pkceCodeChallengeandpkceCodeChallengeMethod.WebUtils.performPar:client_id,response_type,redirect_uri,scope,state, and PKCE (code_challenge,code_challenge_method) plusadditionalParameterstoparEndpointviaPOST(application/x-www-form-urlencoded).request_urifrom the JSON response and stores it.WebUtils.getAuthorizationUrl:request_uriis present, builds an authorization URL withclient_idandrequest_uriinstead of repeating all parameters.getTokenEndpointData:pkceCodeVerifieras thecode_verifierin the token request.Android (AppAuth)
OAuth2Options:parEndpoint,parRequestUri,pkceEnabled, andpkceCodeVerifier(generated once per auth attempt).ParRequestAsyncTask:client_id,response_type,redirect_uri,scope,state, PKCE (code_challengederived frompkceCodeVerifierwith S256, or plain as fallback), andadditionalParameterstoparEndpointviaPOST(application/x-www-form-urlencoded).request_urionOAuth2Options.GenericOAuth2Plugin.startAuthorization:AuthorizationRequest.Builder(state, scope, etc).pkceCodeVerifiertosetCodeVerifierwhen PKCE is enabled.request_uriin the additional parameters when PAR is used.iOS (OAuthSwift)
GenericOAuth2Plugin:requestStateand, whenpkceEnabled, generates a singlepkceCodeVerifierandpkceCodeChallengeper auth attempt.parEndpointis configured:client_id,response_type,redirect_uri,scope,state, PKCE (code_challenge,code_challenge_method=S256when enabled), plusadditionalParameters.POST(application/x-www-form-urlencoded) toparEndpointand extractsrequest_urifrom the JSON response.oauthSwift.authorize:request_urito theparametersdictionary when PAR is used.codeChallenge/codeVerifierpair toauthorize, which is reused by OAuthSwift for the token request.Error handling
If PAR is enabled and fails, the plugin fails fast before opening a browser / external UI:
Web
WebUtils.performParrejects with anErrorwhose message starts withPAR_FAILED::PAR_FAILED: missing request_uri in responsePAR_FAILED: invalid JSON responsePAR_FAILED: HTTP <status> [error - error_description]PAR_FAILED: network errorAndroid
ParRequestAsyncTaskrejects the call with:ERR_PAR_FAILEDPAR_FAILED: ...(HTTP status, JSONerror/error_description, or network/format issues).iOS
ERR_PAR_FAILEDPAR_FAILED: ...(HTTP status, JSON parsing issues, or network error).Logging:
logsEnabledflag continues to control logging behavior.logsEnabledistrue, PAR requests and responses are logged (without printing secrets like client secret, which is not used in this flow).Backward compatibility
parEndpointis not configured:parEndpointis configured:request_urialongside the existing PKCE and state handling.Example configuration (Authelia + PAR + PKCE)
This setup will use PAR + PKCE correctly with providers like Authelia that require both PAR and PKCE, while still allowing non-PAR providers to work by simply omitting
parEndpoint.