Keycloak v24内部客户端令牌交换的受众配置问题
Keycloak v24 内部客户端令牌交换(无全范围授权)解决方案
针对你遇到的「受众不在范围内」错误,以及四个疑问,以下是具体的配置和代码方案:
1. 如何将客户端B添加为客户端A令牌的受众?
无需开启全范围授权,通过给客户端A添加受众映射器即可实现:
- 登录Keycloak控制台,进入目标领域,打开客户端A的配置页面
- 切换到「映射器」标签,点击「创建」
- 映射器类型选择「受众」
- 填写名称(如
add-audience-b) - 勾选「添加到访问令牌」
- 在「受众」字段输入客户端B的ID
- 保存配置
- 重新获取客户端A的访问令牌,此时令牌的
aud字段会同时包含A和B的ID
2. 令牌交换请求中的scope应如何设置?
scope需填写目标客户端(如B)已启用的权限范围:
- 基础场景可填
openid email profile,但要确保这些scope在客户端B的「客户端范围」中已添加 - 如果目标客户端有自定义scope,需同步添加到请求的scope参数中
- 注意:scope是目标令牌需要的权限,而非源令牌的权限,但源令牌必须包含至少匹配的scope,否则会被拒绝
3. 请求中是否需要传入audience参数?若需要,值应为多少?
必须传入,值为目标客户端的ID(如交换为B的令牌则填B的client ID):
- Keycloak v24不支持数组格式的audience,只能传单个字符串
- 该参数用于明确指定要交换的目标令牌受众,避免Keycloak返回错误的令牌
4. 请求中的client_id和client_secret应使用源客户端(A)还是目标客户端(B)的?
必须使用**目标客户端(B)**的ID和密钥:
- 令牌交换本质是向目标客户端发起请求,获取其颁发的令牌,因此需要目标客户端的身份凭证来验证请求合法性
- 使用源客户端A的凭证只会返回A的令牌,无法得到B的令牌
内部客户端令牌交换代码示例(从A交换为B的刷新令牌)
// 基于keycloak-js的令牌交换请求示例 return this.client.grant({ grant_type: "urn:ietf:params:oauth:grant-type:token-exchange", client_id: "client-b-id", // 目标客户端B的ID client_secret: "client-b-secret", // 目标客户端B的密钥 subject_token: "client-a-valid-access-token", // 源客户端A的有效访问令牌 subject_token_type: "urn:ietf:params:oauth:token-type:access_token", requested_token_type: "urn:ietf:params:oauth:token-type:refresh_token", scope: "openid email profile", // 目标客户端B启用的scope audience: "client-b-id" // 目标客户端B的ID,必填 });
额外注意事项
- 确保客户端B的访问类型为
confidential(在客户端B的「设置」标签中配置) - 检查客户端B的「高级」→「令牌设置」,确认「允许令牌交换」已开启
- 源令牌(A的令牌)必须未过期,且包含的scope覆盖请求中指定的scope
内容的提问来源于stack exchange,提问作者Tyrannogyna
相关产品推荐
相关产品推荐

