Keycloak如何实现用户及其所属用户组policy属性的聚合
问题原因
Keycloak 对部分内置声明名有默认的类型约束,policy 属于默认被定义为单值字符串类型的预留声明。当你把用户和用户组的多值属性映射到该声明时,Keycloak 只会保留优先级更高的用户直接属性值,不会自动合并所有匹配值为数组。而你改用 policies 这类非预留声明名时,映射器默认的多值配置会生效,就能正常输出包含所有属性的数组。
解决方案
方案1(推荐):直接使用非预留声明名
如果业务侧可以调整读取令牌字段的逻辑,直接使用 policies 这类未被Keycloak预留的声明名即可,无需额外修改Keycloak配置,兼容性最高。
方案2:强制保留policy声明名输出数组
如果必须使用policy作为声明名,按以下步骤配置:
- 打开你当前创建的属性映射器配置页,开启「Multivalued(多值)」开关,保存后重新生成令牌测试。
- 如果上述操作仍不生效,可以替换为脚本映射器手动合并属性:
- 首先开启Keycloak的脚本功能:Quarkus版本Keycloak启动时添加启动参数
--features=scripts,WildFly版本在配置文件中启用脚本提供方。 - 新建类型为
Script Mapper的客户端映射器,填入以下脚本内容:
var policyValues = []; // 读取用户属性 var userPolicy = user.getAttributeFirst("policy"); if (userPolicy) policyValues.add(userPolicy); // 读取所有所属用户组的属性 user.getGroups().forEach(group => { var groupPolicy = group.getAttributeFirst("policy"); if (groupPolicy) policyValues.add(groupPolicy); }); // 写入声明强制输出数组 token.setOtherClaims("policy", policyValues);- 保存映射器后重新登录获取令牌验证即可。
- 首先开启Keycloak的脚本功能:Quarkus版本Keycloak启动时添加启动参数
内容的提问来源于stack exchange,提问作者plugandplay
相关产品推荐
相关产品推荐

