如何通过Keycloak API使用常规令牌请求自定义生命周期短令牌?
Great question! This is exactly the kind of scenario where Keycloak's Token Exchange feature shines—let me walk you through how to implement this step by step.
We'll use Keycloak's Token Exchange grant type to swap your existing long-lived access token for a short-lived 15-second one that's safe to use in query parameters for file downloads. This avoids exposing a long-lived token in browser history or logs.
First, make sure your client is set up to allow token exchange:
- Go to your Keycloak admin console → Select your target realm → Clients → Choose your API client.
- Under Settings, confirm your client's Access Type is set appropriately (use
confidentialfor server-side clients,publicfor browser-based clients). - Navigate to Advanced → Enabled Grant Types and check the box for Token Exchange. Save your changes.
Keycloak may enforce a minimum access token lifespan by default. To allow 15-second tokens:
- For realm-wide settings: Go to Realm Settings → Tokens, find Access Token Lifespan, and set the minimum value to 15 seconds.
- For client-specific settings: In your client's configuration, go to Settings → Advanced Settings → Access Token Lifespan and set it to 15 seconds (this overrides the realm default). Save changes.
Use the /realms/{realm_id}/protocol/openid-connect/token endpoint with the following parameters to swap your long-lived token for a short-lived one:
Request Details
- Method: POST
- Content-Type:
application/x-www-form-urlencoded - Required Parameters:
grant_type: Must beurn:ietf:params:oauth:grant-type:token-exchange(tells Keycloak we're performing a token swap)subject_token: Your valid, long-lived access tokensubject_token_type:urn:ietf:params:oauth:token-type:access_token(specifies the type of token being exchanged)expires_in:15(desired lifespan of the new token, in seconds)client_id: Your client's ID (required for all clients)client_secret: Only required if your client is set toconfidential
Example cURL Request
curl -X POST 'https://your-keycloak-domain/realms/your-realm-id/protocol/openid-connect/token' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'grant_type=urn:ietf:params:oauth:grant-type:token-exchange' \ -d 'subject_token=eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6IC...' \ -d 'subject_token_type=urn:ietf:params:oauth:token-type:access_token' \ -d 'expires_in=15' \ -d 'client_id=your-api-client-id' \ -d 'client_secret=your-client-secret' # Omit this line for public clients
Sample Response
You'll receive a JSON response with the short-lived token, confirming its 15-second lifespan:
{ "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6IC...", "expires_in": 15, "token_type": "Bearer", "scope": "openid email profile" }
Now you can safely append this short-lived token to your download URL:
https://api.service.io/users.xlsx?accessToken=SHORT_LIVED_TOKEN
- The short-lived token inherits all permissions (scopes) from the original access token, so it will work for the same API endpoints.
- Since the token expires in 15 seconds, even if it's logged in browser history or server logs, it will be useless shortly after the download completes.
- Be sure to handle token exchange failures (e.g., expired original token, insufficient permissions) in your client code.
内容的提问来源于stack exchange,提问作者Lorent Lempereur

