Keycloak中如何从access_token排除指定客户端及对应角色
可行实现方案
方案1:自定义脚本型令牌映射器(推荐,无需改动Keycloak核心代码)
- 首先进入Keycloak admin控制台,进入对应领域(Realm)的**客户端作用域(Client Scopes)**页面,找到
roles作用域,进入「映射器(Mappers)」标签页 - 找到默认的
client roles映射器,先把它禁用,避免默认把所有客户端角色都写入令牌 - 点击「创建映射器」,类型选择「脚本映射器(Script Mapper)」,注意如果是Keycloak 17+的Quarkus版本,需要提前在启动参数里开启脚本功能:
--features=scripts - 映射器配置项参考:
- 名称:自定义过滤客户端角色
- 令牌声明名称:
resource_access(和默认的声明名保持一致,不影响上层业务解析) - 适用场景勾选
访问令牌(Access Token) - 脚本部分填写过滤逻辑,示例代码(把里面的
exclude_client_id换成你要移除的客户端ID):
// 拿到用户所有客户端角色 var resourceAccess = user.getResourceAccess(); // 定义要排除的客户端ID var excludeClientId = "你要移除的客户端ID"; // 过滤掉指定客户端 if (resourceAccess.containsKey(excludeClientId)) { resourceAccess.remove(excludeClientId); } // 返回处理后的resourceAccess对象 return resourceAccess; - 保存配置后重新签发令牌,指定客户端的相关信息就会从
resource_access字段里移除,其余客户端信息不受影响
方案2:自定义Java协议映射器(性能更优,适合生产环境对稳定性要求高的场景)
- 引入Keycloak服务SPI依赖,继承
org.keycloak.protocol.oidc.mappers.AbstractOIDCProtocolMapper类 - 重写
setAccessTokenClaim方法,在方法内实现和上述脚本逻辑一致的过滤逻辑,移除指定客户端的resource_access条目 - 把写好的扩展打包成jar,放到Keycloak的
providers目录,重启Keycloak后就能在控制台的映射器列表里看到你自定义的映射器,后续配置逻辑和方案1一致 - 这个方案不需要开启脚本功能,执行效率更高,也不会有脚本执行的安全风险
方案3:单客户端专属过滤(仅针对特定客户端签发的令牌生效)
如果你不需要全局所有令牌都过滤,只有某一个客户端申请的access_token需要移除指定客户端信息,可以直接在该客户端的「映射器」标签下单独配置上述的过滤逻辑,不需要修改全局的roles客户端作用域配置,不会影响其他客户端的令牌内容
注意事项
- 操作前建议先导出当前领域的配置做备份,避免配置错误导致令牌签发异常
- 如果你的角色信息同时还写到了
realm_access或者其他自定义声明里,需要同步在映射器里添加对应字段的过滤逻辑 - Keycloak版本更新后建议验证映射器逻辑是否正常运行,避免版本接口变动导致过滤失效
内容的提问来源于stack exchange,提问作者Nikhil Lingam
相关产品推荐
相关产品推荐

