-
-
Notifications
You must be signed in to change notification settings - Fork 0
Authorization Code Redemption
Authorization code redemption is the process by which a client redeems a previously issued authorization code in exchange for access and refresh tokens.
---
title: Authorization Code Redemption
---
sequenceDiagram
autonumber
actor Client
participant Authorization Service
participant Data Layer
Client-->>Authorization Service: Calls the token endpoint with authorization code and code verifier
Note right of Client: POST /oauth/token
Authorization Service-->>Data Layer: Retrieves authorization code and code challenge
Authorization Service-->Authorization Service: Verifies code verifier with code challenge
Authorization Service-->Authorization Service: Generates access and refresh tokens
Authorization Service-->>Data Layer: Creates an OAuth Session record with token JTI's
Authorization Service-->>Client: Returns access and refresh tokens to client
The Client entity represents a client application registered with the OAuth provider.
The Authorization Service entity represents the component of the application which is responsible for redeeming the authorization code and issuing access and refresh tokens. This is provided by TokenAuthority.
The Data Layer entity is a relational database used for storing data related to authorization grants and OAuth sessions.
The client calls the POST /oauth/token endpoint to redeem an authorization code for access and refresh tokens. The endpoint responds with either an error code conforming to RFC-6749 or a JSON object containing the access and refresh tokens.
HTTP Method: POST
URL: /oauth/token
Content-Type: application/x-www-form-urlencoded
Params:
| Param | Required? | Description |
|---|---|---|
| grant_type | yes | The authorization grant type for the authorization code grant process. Must be authorization_code. |
| code | yes | The authorization code previously issued to the client during the authorization process. |
| code_verifier | yes (public clients) | The code verifier used to generate the code challenge provided during the authorization process. |
| redirect_uri | yes (public clients) | The redirect URI that was used in the authorization request. Must match exactly. |
| client_id | no | The client identifier. Required for public clients if not already authenticated. |
| scope | no | Space-separated list of scope tokens. Must be a subset of scopes granted during authorization. |
| resource | no | Target resource URI(s) for the access token (RFC 8707). Must be a subset of resources granted during authorization. Can be repeated for multiple resources. |
Example Request:
POST /oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
code=02a456ce-73a5-416d-8159-7c8bff9a19e5&
code_verifier=CR70DhqQkvzPL2JjlQNyiCNgoRDZj2jko0mW7CpEUXJPgK-uEeQoZCSJlBgup73MtqpdeYRLmA&
redirect_uri=http://localhost:8080/callback
Example Request with Scope Downscoping:
POST /oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
code=02a456ce-73a5-416d-8159-7c8bff9a19e5&
code_verifier=CR70DhqQkvzPL2JjlQNyiCNgoRDZj2jko0mW7CpEUXJPgK-uEeQoZCSJlBgup73MtqpdeYRLmA&
redirect_uri=http://localhost:8080/callback&
scope=read
Example Request with Resource Indicators (RFC 8707):
POST /oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
code=02a456ce-73a5-416d-8159-7c8bff9a19e5&
code_verifier=CR70DhqQkvzPL2JjlQNyiCNgoRDZj2jko0mW7CpEUXJPgK-uEeQoZCSJlBgup73MtqpdeYRLmA&
redirect_uri=http://localhost:8080/callback&
resource=https://api.example.com/
Example Response:
{
"access_token": "eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjMwMDAvYXBpLyIsImlhdCI6MTY5NTE0MDY1NiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDozMDAwLyIsImp0aSI6Ijc0YjVkZTlkLTQ4YmQtNDFjNC1hMGNiLWZjYzM0OWU3MTY2NyIsInVzZXJfaWQiOjMsImV4cCI6MTY5NTE0MDk1Nn0.aUhztv6x2-foSfp17W_7-mMC-w3HKUx25pMSWHYjzqY",
"refresh_token": "eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjMwMDAvYXBpLyIsImlhdCI6MTY5NTE0MDY1NiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDozMDAwLyIsImp0aSI6IjUxMGJhNTdiLTgwNTQtNGQxYi1iYWQ1LTVmZmZjOWE0NzA4ZCIsImV4cCI6MTY5NjM1MDI1Nn0.6-7DgP4UFcA7hEkK7XRob_sRNEGH1QlvalysDJjBrko",
"token_type": "bearer",
"expires_in": 300
}Response Fields:
| Field | Description |
|---|---|
| access_token | A JWT access token for authenticating API requests. |
| refresh_token | A JWT refresh token for obtaining new access tokens. |
| token_type | The token type. Always bearer. |
| expires_in | The number of seconds until the access token expires. |
| scope | Space-separated list of scopes granted (only included if scopes were requested). |
Error Response:
{
"error": "invalid_grant"
}Common error codes:
-
invalid_grant- The authorization code is invalid or has already been redeemed. -
invalid_request- The request is missing required parameters or the code verifier is invalid. -
invalid_scope- The requested scope is invalid or was not granted during authorization. -
invalid_target- The requested resource is invalid or was not granted during authorization (RFC 8707).
When scopes are requested (either during authorization or at token exchange), the access token's scope claim contains the space-delimited scope tokens. The token response also includes a scope field echoing the granted scopes.
Resource servers should validate that required scopes are present in the token's scope claim before allowing access to protected resources.
At token exchange, clients can request a subset of the scopes that were granted during authorization. This allows obtaining tokens with minimal necessary permissions:
# During authorization, user granted read and write scopes
scope=read write
# At token exchange, client only needs read access
scope=read
If no scope parameter is provided at token exchange, the token is issued with all scopes granted during authorization.
When resources are requested (either during authorization or at token exchange), the access token's aud claim is set to the requested resource URI(s):
-
Single resource:
audis a string containing the resource URI -
Multiple resources:
audis an array of resource URIs
Resource servers should validate that their URI is present in the aud claim before accepting the token.
At token exchange, clients can request a subset of the resources that were granted during authorization. This allows obtaining tokens with minimal necessary permissions:
# During authorization, user granted access to both APIs
resource=https://api.example.com/&resource=https://billing.example.com/
# At token exchange, client only needs the main API
resource=https://api.example.com/
If no resource parameter is provided at token exchange, the token is issued for all resources granted during authorization.
Getting Started
- Installation Guide
- MCP Quickstart
- Configuration Reference
- User Authentication
- Protecting API Endpoints
- Customizing Views
- Event Logging
- Instrumentation
Process Flows
- Authorization Code Grant
- Authorization Code Redemption
- Token Refresh
- Token Revocation
- Authorization Server Metadata
- Protected Resource Metadata
- Dynamic Client Registration
- Client Metadata Documents
Development