










门户 GET /kc/exchange-token 新流程:
POST /internal/wso2/token/authz-user → 得到 kcUserId(来自 idn_oauth2_access_token.AUTHZ_USER)wso2 做 client_credentials 拿到服务账号 tokenrequested_subject={kcUserId},签发该用户的 KC access_token因此 不要求 WSO2 应用 token 带 openid scope,但要求 Keycloak 客户端具备 Service Account + Token Exchange(用户模拟) 权限。
以下以客户端 ID wso2、Realm fabao 为例(与 application-*.yml 中 keycloak.client-id 一致)。
登录 Keycloak Admin Console → Realm fabao → Clients → wso2:
| 项 | 建议值 |
|---|---|
| Client authentication | On |
| Authentication flow / Standard flow | 按现有对接保留 |
| Service accounts roles | On(必须,用于 client_credentials) |
| Direct access grants | 可不依赖 |
| Valid redirect URIs / Web origins | 按现有配置 |
保存后,在 Credentials 页确认 client-secret 与各环境 KEYCLOAK_WSO2_CLIENT_SECRET / yml 一致。
不同 Keycloak 大版本菜单位置略有差异,目标是:允许客户端 wso2 用自己的服务账号 token,对任意(或指定)用户做 requested_subject 交换。
wso2 → Permissions(或 Authorization)token-exchange、可能还有 impersonate 等)wso2token-exchange Permission 并 Save
requested_subject 属于「用 A 的 token 换 B 用户的 token」,除 token-exchange 外通常还要 impersonation:
方式 A(常用,粒度到用户权限):
方式 B(服务账号角色,配置简单,权限较大):
wso2 → Service account rolesimpersonation(必须)方式 B 权限面更大(可模拟 realm 内用户),仅限受信的内部客户端
wso2,密钥严格保管。

若换出的用户 token 需要特定 audience 或 scope(门户后续 jwt-bearer 进 APIM 依赖 claim):
wso2 → Client scopes:保证默认 scope 含业务所需(至少 openid,与 yml keycloak.scope 一致)scope=openid(可配置)把 {KC_TOKEN_URI}、{CLIENT_ID}、{CLIENT_SECRET}、{KC_USER_ID} 换成实际值。
curl -s -X POST '{KC_TOKEN_URI}' \
-u '{CLIENT_ID}:{CLIENT_SECRET}' \
-d 'grant_type=client_credentials' \
-d 'scope=openid'
应返回 access_token。记下为 ACTOR_TOKEN。
curl -s -X POST '{KC_TOKEN_URI}' \
-u '{CLIENT_ID}:{CLIENT_SECRET}' \
-d 'grant_type=urn:ietf:params:oauth:grant-type:token-exchange' \
-d 'subject_token={ACTOR_TOKEN}' \
-d 'subject_token_type=urn:ietf:params:oauth:token-type:access_token' \
-d 'requested_token_type=urn:ietf:params:oauth:token-type:access_token' \
-d 'requested_subject={KC_USER_ID}' \
-d 'scope=openid'
成功:返回用户 access_token;解码 JWT 后 sub(或等价用户标识)应为该用户。
常见失败:
| 现象 | 处理 |
|---|---|
Client not allowed to exchange / not allowed to impersonate |
补全 2.2 / 2.3 |
Client not enabled for service accounts |
打开 Service accounts roles |
Invalid user credentials / user not found |
确认 AUTHZ_USER / kcUserId 是 Realm 内真实用户 ID(UUID)或用户名,与 Keycloak 用户匹配 |
unauthorized_client |
client-secret 或 client-id 错误 |
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。