Keycloak 18.0:如何在JWT中关联组与对应角色
实现Keycloak JWT中组与角色的关联键值对结构
可以实现,核心是用Keycloak的**Script Mapper(脚本映射器)**替代默认的Group Membership映射器,自定义生成包含组-角色对应关系的JSON结构。以下是具体操作步骤:
操作步骤
进入目标Client Scope配置
登录Keycloak控制台,进入对应Realm,依次点击Clients-> 目标客户端的Client Scopes-> 选择你正在使用的profileClient Scope(也可新建专用Scope)。移除原有映射器
删除原有的Group Membership映射器(若需保留原有groups字段可跳过此步,改用新的Claim名称)。添加脚本映射器
点击Create,选择Script Mapper类型,配置以下基础信息:- Name:自定义名称(如
Group-Role Mapping) - Mapper Type:Script Mapper
- Token Claim Name:
groups(或自定义名称如group_roles) - Claim JSON Type:
JSON - 按需开启
Add to ID token和Add to access token
- Name:自定义名称(如
编写自定义脚本
在Script编辑框中粘贴以下脚本,该脚本会遍历用户所属的所有组(含子组),生成以组路径为键、角色列表为值的结构:var groupRoles = {}; // 获取用户所有组(包含子组) var groups = user.getGroups(); for each (var group in groups) { // 获取组的完整路径(如/proj1/admin) var groupPath = group.getPath(); // 收集该组分配的所有角色名称 var roleNames = []; var roles = group.getRoles(); for each (var role in roles) { roleNames.push(role.getName()); } // 存入组-角色映射对象 groupRoles[groupPath] = roleNames; } // 将映射结构写入JWT Claim token.setClaim("groups", groupRoles);
自定义调整说明
- 若需区分客户端角色与Realm角色,可在脚本中添加过滤逻辑,仅保留目标客户端的角色:
// 替换为你的客户端ID var targetClientId = "your-client-id"; var clientRoles = group.getClientRoles(targetClientId); - 若不需要组的完整路径,可改用组的显示名称:
group.getName() - 如需排除继承的角色,可调用
group.getRealmRolesDirectly()或group.getClientRolesDirectly()获取直接分配的角色。
验证效果
生成新的JWT后,groups字段会呈现类似以下的键值对结构:
"groups": { "/proj1/admin": ["ADMIN_ROLE"], "/proj2/editor": ["EDITOR_ROLE"], "/proj1/guest": ["VIEWER_ROLE"] }
注意事项
- 确保Realm已启用脚本功能:进入
Realm Settings->Features,开启Scripts选项。 - 生产环境使用脚本时,需避免潜在的代码注入风险,仅使用可信逻辑。
内容的提问来源于stack exchange,提问作者binocla
相关产品推荐
相关产品推荐

