You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Keycloak如何提取用户属性中的角色值并写入JWT令牌?

Keycloak将用户属性中存储的外部角色写入JWT的实现方案

有两种成熟可落地的方案,按需选择即可:

方案1:内置脚本映射器(零代码,适合测试/快速验证场景)

不需要写自定义代码,直接用Keycloak自带的脚本映射能力实现:

  • 进入目标Realm的客户端管理页,选择需要签发令牌的对应客户端,切换到Client scopes标签页
  • 找到该客户端关联的专用scope(命名规则一般为[客户端ID]-dedicated),进入详情后点击Add mapper > By configuration
  • 选择Script Mapper类型,按以下规则填写配置:
    • Name:自定义即可,比如External Roles Injector
    • Token Claim Name:留空,因为我们直接修改JWT原生的角色字段,不需要新增自定义claim
    • Claim JSON Type:选择JSON
    • 按需勾选Add to ID token、Add to access token选项,决定角色注入的令牌类型
    • 脚本区域填入以下逻辑,注意替换成你实际存储角色的用户属性名:
// 读取用户属性中预存的外部角色列表,替换为你实际的属性名
var externalRoles = user.getAttribute("external_roles");
// 获取令牌原生的realm级角色容器,不存在则初始化
var realmAccess = token.getRealmAccess();
var roleSet = realmAccess.getRoles() || java.util.Collections.emptySet();

// 合并外部角色到原生角色集合
if (externalRoles && externalRoles.size() > 0) {
    externalRoles.forEach(function(roleItem) {
        // 如果你的角色是逗号分隔的单值字符串,用split拆分;多值用户属性可直接遍历
        roleItem.split(",").forEach(function(role) {
            role = role.trim();
            if (role) roleSet.add(role);
        })
    })
}
realmAccess.setRoles(roleSet);

// 如需写入客户端级角色,替换对应客户端ID后启用以下代码
// var clientResource = token.getResourceAccess("目标客户端ID");
// clientResource.setRoles(/* 同上角色合并逻辑 */);

return token;
  • 保存配置后,重新签发令牌即可看到角色已经写入标准的realm_access.roles字段。

方案2:自定义OIDC协议映射器(生产环境推荐)

大部分生产环境部署会默认禁用Keycloak的脚本执行能力,这种场景下推荐开发自定义协议映射器SPI:

  • 新建Java Maven项目,引入keycloak-server-spi、keycloak-server-spi-private、keycloak-services三个官方依赖,scope设为provided
  • 新建映射器类继承AbstractOIDCProtocolMapper,重写setClaim方法,核心逻辑和上述脚本一致:从UserModel实例中读取存储外部角色的用户属性,拆分/格式化后合并到AccessToken对象的realmAccess或对应客户端的resourceAccess角色集合中
  • 按照Keycloak SPI规范,在resources/META-INF/services目录下添加SPI注册配置文件
  • 项目打包为jar后,上传到Keycloak部署路径的providers目录,执行kc.sh build命令重启Keycloak
  • 重启后即可在映射器配置列表看到自定义的映射器,配置方式和内置映射器完全一致,支持所有客户端/全局Scope复用。

校验注意事项

  • 如果你存储角色的用户属性是单值字符串格式,必须先做拆分和去空处理,避免把整串字符识别为单个角色
  • 如果需要所有客户端签发的令牌都默认携带这些外部角色,不要在客户端专属Scope下配置映射,进入Realm全局的Client Scopes菜单配置映射后,绑定到默认启动的Scope即可
  • 验证时可以直接用admin-cli客户端调用令牌接口获取令牌,解码后检查realm_access.roles字段是否符合预期。

内容的提问来源于stack exchange,提问作者stacktrace2234

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 07:39:19