Section 7: Authorizing a Consent
After submitting your consent request via the PAR endpoint and receiving a request_uri, the next step is redirecting your user to the OFP's authorization endpoint. The user will then authenticate, review the consent details, select accounts to share, and be redirected back to your application.
Overview
The consent authorization flow involves:
- Redirecting the user to the OFP's authorization endpoint
- User actions at the OFP (authentication, account selection, consent grant)
- Callback to your application with either success or error information
- Handling the response in your application
This process follows the OAuth 2.0 authorization code flow with PKCE security.
Step 1: Redirect User to Authorization Endpoint
Building the Authorization URL
FAPI 2.0 requires Pushed Authorization Requests (PAR), which means authorization request details are already submitted to the server. The authorization endpoint call is therefore minimal - only two parameters:
GET {{authorization_endpoint}}?client_id={{CLIENT_ID}}&request_uri={{REQUEST_URI}}
Parameters:
client_id: Your registered OIDC client IDrequest_uri: The URN received from the PAR endpoint (e.g.,urn:ietf:params:oauth:request_uri:550e8400-e29b-41d4-a716-446655440000)
Note: response_type and response_mode are NOT included here - they're already in the JAR you submitted to the PAR endpoint.
Example Redirect (Node.js)
const authorizationUrl = new URL('{{authorization_endpoint}}');
authorizationUrl.searchParams.append('client_id', '{{CLIENT_ID}}');
authorizationUrl.searchParams.append('request_uri', requestUri); // from PAR response
// Redirect user browser
res.redirect(authorizationUrl.toString());
Example Redirect (Python)
from urllib.parse import urlencode
params = {
'client_id': '{{CLIENT_ID}}',
'request_uri': request_uri, # from PAR response
}
authorization_url = f"{{authorization_endpoint}}?{urlencode(params)}"
# Redirect user browser
return redirect(authorization_url)
Step 2: What Happens at the OFP
User Experience During Authorization
When the user is redirected to the OFP, the following occurs:
1. Provider Selection (if needed)
- If you did not specify
dp_idin your consent request, the OFP presents the user with a list of available Data Providers - The user selects which institution (bank, fintech, etc.) they want to connect to
- If you specified
dp_id, this step is skipped and the user proceeds directly to authentication
2. User Authentication
- The user is redirected to their selected Data Provider's login portal
- The user authenticates with their credentials (username, password, 2FA, etc.)
- The Data Provider confirms their identity to the OFP
3. Account and Consent Review
- The user is presented with:
- A list of their accounts at the Data Provider
- The specific consent purpose and data types being requested (from your consent request)
- The expiration date of the consent
- The user selects which accounts they wish to share with your application
- The user reviews the permissions and either grants or denies consent
4. Redirect Back to Your Application
- After the user grants (or denies) consent, the OFP redirects the user's browser to your registered
redirect_uri - The redirect includes either:
- Success: An authorization
code(a short-lived token) - Error: An error code explaining why authorization failed
- Success: An authorization
Step 3: Handle the Redirect Response
Success Scenario
When the user grants consent, the OFP redirects to your redirect_uri with an authorization code:
https://your-app.com/oauth/callback?code=eyJhbGci...&state=550e8400-e29b-41d4-a716-446655440000
Response Parameters:
code: Authorization code (typically a short-lived token, valid for ~10 minutes)state: Your original state value from the JAR request (verify this matches)
Your Application Should:
- Verify the
stateparameter matches what you stored during Step 2 of Creating a Consent- Prevents CSRF attacks if state doesn't match, reject the request
- Extract the
codeparameter - Exchange the code for tokens using the token endpoint (see Section 8: Token Exchange)
- Redirect user to a success page in your application
Error Scenario
If the user denies consent or an error occurs, the OFP redirects with an error:
https://your-app.com/oauth/callback?error=access_denied&error_description=User+denied+the+consent&state=550e8400-e29b-41d4-a716-446655440000
Error Response Parameters:
error: Error code (e.g.,access_denied,invalid_request,server_error)error_description: Human-readable description of the error (URL-encoded)state: Your original state value
Common Error Codes:
access_denied: User explicitly denied consentinvalid_request: Request was invalid (missing parameters, expired PAR request)server_error: Error at OFP or Data Providertemporarily_unavailable: Temporarily unable to process request
Your Application Should:
- Verify the
stateparameter (same as success scenario) - Log the error for debugging
- Display appropriate message to the user (e.g., "Consent was not granted. Please try again.")
- Optionally retry or offer the user an alternative action
Example Response Handler (Node.js)
app.get('/oauth/callback', (req, res) => {
const { code, error, error_description, state } = req.query;
// Verify state
const storedState = req.session.state; // stored during Step 2
if (state !== storedState) {
return res.status(400).send('State mismatch - possible CSRF attack');
}
// Handle error
if (error) {
console.error(`Authorization error: ${error} - ${error_description}`);
return res.status(400).send(`Authorization failed: ${error_description}`);
}
// Handle success
if (code) {
// Exchange code for tokens (see Section 8)
exchangeAuthorizationCode(code)
.then(tokens => {
// Store tokens and redirect to success page
req.session.accessToken = tokens.access_token;
req.session.idToken = tokens.id_token;
res.redirect('/dashboard');
})
.catch(err => {
console.error('Token exchange failed:', err);
res.status(500).send('Token exchange failed');
});
}
});
Example Response Handler (Python)
from flask import request, redirect, session
@app.route('/oauth/callback')
def oauth_callback():
code = request.args.get('code')
error = request.args.get('error')
error_description = request.args.get('error_description')
state = request.args.get('state')
# Verify state
stored_state = session.get('state')
if state != stored_state:
return 'State mismatch - possible CSRF attack', 400
# Handle error
if error:
app.logger.error(f'Authorization error: {error} - {error_description}')
return f'Authorization failed: {error_description}', 400
# Handle success
if code:
try:
# Exchange code for tokens (see Section 8)
tokens = exchange_authorization_code(code)
# Store tokens
session['access_token'] = tokens['access_token']
session['id_token'] = tokens['id_token']
return redirect('/dashboard')
except Exception as e:
app.logger.error(f'Token exchange failed: {e}')
return 'Token exchange failed', 500
Important: No Redirect Scenario
In rare situations, the OFP may not redirect back to your application at all. This can occur due to:
Technical Issues:
- Network failures during the redirect
- User closes browser before redirect completes
- Server-side issues at OFP or Data Provider
- Timeout - User takes too long to complete authorization
Security Issue:
- Malformed or invalid authorization request - If the authorization request contains incorrectly formed parameters (e.g., invalid JAR signature, expired
request_uri, tampered claims), the OFP considers the request potentially malicious. For safety, it will NOT redirect back, as redirecting an attacker to your registeredredirect_uricould enable further attacks. Instead, the user sees an error page at the OFP.
What to do:
- Implement a timeout mechanism in your application (typically 10-15 minutes)
- If the user hasn't returned within the timeout, prompt them to retry the consent flow
- Verify your authorization request is correctly formed:
- JAR signature is valid (PS256)
request_urihasn't expired (PAR endpoint returns 600 second TTL)- All claims in JAR are valid and not tampered
- Provide feedback to users: "Authorization did not complete. Please try again or contact support."
Step 4: Store Important Values
Before proceeding to token exchange, securely store:
- Authorization
code- Needed for immediate token exchange request_uri- May be needed for debugging or refreshing consentstate- Keep until verified in callbackcode_verifier- Needed for token exchange (PKCE)
These values should be tied to a user session and cleared after successful token exchange.
Next Steps
Once you have the authorization code:
- Section 8: Token Exchange - Exchange the authorization code for access and ID tokens
Related Documentation
- Section 6: Creating a Consent - How to initiate the consent request
- Client Authentication Methods - Details on OIDC authentication
- FAPI 2.0 Security Profile - Security requirements and best practices
- Previous
- Creating Consents
- Next
- Token Exchange