This article focuses on unified authentication between WSO2 and Keycloak. The core idea is to connect user tokens, application tokens, and API access flows through authorization_code, jwt-bearer, and token exchange, solving identity fragmentation and token inconsistency across platforms. Keywords: WSO2, Keycloak, Token Exchange.
Technical Specifications at a Glance
| Parameter | Details |
|---|---|
| Core topic | Unified authentication integration between WSO2 and Keycloak |
| Primary languages | Java, configuration-driven setup, OAuth 2.0 standard protocols |
| Key protocols | OAuth 2.0, OIDC, JWT, Token Exchange |
| Authorization grants | authorization_code, client_credentials, urn:ietf:params:oauth:grant-type:jwt-bearer |
| Architectural roles | Keycloak as the IdP, WSO2 as the developer platform and gateway |
| Stars | Not provided in the source |
| Core dependencies | Keycloak, WSO2 API Manager, API Gateway |
This integration pattern unifies user identity and application access credentials
The core idea behind the original flow is straightforward: Keycloak handles centralized identity authentication, while WSO2 manages the API lifecycle, application provisioning, and gateway access. These systems do not compete with each other; instead, they collaborate across the identity domain and the API domain.
The challenge is that API clients often need both application-level authorization and user-level identity context. If you use only a WSO2 token or only a Keycloak token, some resource scenarios will still expose capability gaps.
A dual-token model is necessary
The first layer is the application token, which identifies which client application is calling the service. The second layer is the user token, which identifies which user is accessing the resource. The former fits machine-to-machine access, while the latter fits business APIs that must propagate end-user identity.
User identity = who is accessing
Application identity = which client is accessing
Unified authentication goal = let the API understand both identities
This definition captures the essence of the solution: it does not replace OAuth. Instead, it clearly separates responsibilities across different authorization subjects.
The login phase establishes a trusted identity in Keycloak first
The user first signs in through Keycloak and obtains an auth_code. Then the WSO2 Developer Portal uses that auth_code to exchange for an access_token from Keycloak, and finally generates a WSO2 user token through the jwt-bearer grant.
This step means WSO2 does not directly manage the primary identity. It consumes the authentication result already established by Keycloak. This approach avoids duplicate sign-ins and redundant user systems, and it helps consolidate organizations, roles, and SSO in Keycloak.
# 1. Exchange the auth_code for an access token from Keycloak
curl -X POST https://keycloak.example.com/realms/demo/protocol/openid-connect/token \
-d "grant_type=authorization_code" \
-d "code=AUTH_CODE" \
-d "client_id=wso2-devportal" \
-d "client_secret=SECRET"
# 2. WSO2 uses jwt-bearer to exchange for its own user token
# Core logic: map Keycloak's authenticated result into a user context that WSO2 can recognize
This flow completes the conversion from an external identity to a platform-internal session.
The application creation phase generates the consumer_key and consumer_secret
After the user signs in to the WSO2 Developer Portal, they can create an application. Once the application is created, the platform issues a consumer_key and consumer_secret, which form a standard set of OAuth client credentials.
The client then uses client_credentials to generate an app token. This token can be either a JWT or a reference token. JWTs make gateway-side signature validation fast, while reference tokens make centralized revocation and auditing easier on the server side.
The application token proves the client, not the user
Many teams make the same incorrect assumption: once they obtain an app token, they can access all resources. In reality, an app token is better suited for public APIs, internal tool APIs, or pure machine-to-machine services. It does not inherently carry end-user identity.
# Generate an app token with the application credentials
curl -X POST https://wso2.example.com/oauth2/token \
-u "consumer_key:consumer_secret" \
-d "grant_type=client_credentials"
# Core logic: validate the application identity and then issue an application-level token
This request proves only that the application is authorized. It does not automatically prove that a user has been authenticated.
The API access phase reveals the boundary between WSO2 tokens and Keycloak tokens
When client tools such as Cherry Studio or Cursor connect to an API or MCP service, they typically present an app token to the WSO2 gateway first. If the resource requires only application permissions, the call can complete at that point.
However, if the target API also requires user identity from the unified authentication domain, the gateway must further exchange the WSO2-side token for a Keycloak token. At that point, Keycloak’s Token Exchange capability becomes the bridge across the entire design.
Gateway-side token exchange isolates complexity from clients
The most practical design is not to make every client understand two token systems. Instead, handle the conversion uniformly at the gateway layer. This keeps clients integrated only with WSO2, while the gateway manages identity coordination. The architecture becomes more stable and easier to audit.
import requests
# Core logic: exchange a WSO2 token for a Keycloak token
payload = {
"grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
"subject_token": "WSO2_ACCESS_TOKEN", # Source token to exchange
"requested_token_type": "urn:ietf:params:oauth:token-type:access_token",
"client_id": "gateway-client",
"client_secret": "gateway-secret"
}
resp = requests.post(
"https://keycloak.example.com/realms/demo/protocol/openid-connect/token",
data=payload,
)
print(resp.json()) # Output the unified Keycloak access token
This code shows how a gateway or middleware layer can convert a platform token into a token trusted by the unified identity system.
The sequence diagram clearly defines the responsibility boundaries across roles
The sequence diagram in the source includes five actors: the user, the client, the WSO2 gateway, the WSO2 Developer Portal, and the Keycloak IdP. Its emphasis is not a single login event, but a complete closed loop of login, application creation, application token issuance, resource access, and token exchange.
Because of that, this is not a traditional single sign-on pattern. It is an identity governance design that covers the full lifecycle of API consumption.
The images provide page-level context rather than technical architecture evidence
AI Visual Insight: This image is a donation QR code. It does not contain authentication protocols, system architecture, or interface interaction details, so it can be treated as a supporting page element unrelated to the technical narrative.
AI Visual Insight: This image is closer to an author notice or social information panel. It does not show WSO2, Keycloak, JWT structures, protocol messages, or gateway topology, so it does not serve as key technical evidence.
AI Visual Insight: This animated image is used for page-sharing guidance. It does not include interface fields, authentication redirects, authorization responses, or token claims, so it does not directly help explain the authentication flow.
Production rollout must validate token mapping and permission model consistency first
First, verify that users, roles, and groups in Keycloak can be correctly recognized by WSO2. Second, verify that the target token produced through token exchange preserves the claims required by the API. Third, verify that gateway caching and token expiration settings do not introduce identity drift.
If claim mapping is incomplete, the system will show the classic symptom of a successful login followed by a 403 on the API. If the audience configuration is incorrect, you will see a token that is technically valid but still rejected by the resource server.
security:
identity_provider: keycloak
api_gateway: wso2
token_exchange:
enabled: true
source_token: wso2_token # Source token comes from WSO2
target_token: keycloak_token # Target token is used for unified resource access
checks:
- audience
- issuer
- roles
- expiration
This configuration snapshot summarizes the most common validation points in production environments.
FAQ
If WSO2 can already issue tokens, why exchange them for Keycloak tokens?
Because the trust anchor of the target resource may reside in Keycloak. A WSO2 token can prove that the caller has been authorized by the platform, but it may not satisfy the validation requirements of the unified identity domain, user roles, or downstream resource servers.
Can an app token generated through client_credentials directly represent a user?
No. It represents only the application, not a specific user. If an API requires user identity, user roles, or an auditable subject, you still need a user token or a token exchange step.
Where is the best place to implement token exchange?
The gateway or a centralized identity middleware layer is usually the best place. This design reduces complexity, centralizes auditing, enables shared caching, and avoids forcing different clients to separately adapt to both WSO2 and Keycloak protocol details.
Core summary: This article reconstructs the WSO2 and Keycloak Token Exchange integration flow, covering the critical path from Keycloak login to WSO2 user token acquisition, application credential generation, and gateway-side token conversion, helping teams build a unified identity and secure API access architecture.