Keycloak:如何将IDP返回的嵌套数组映射为多值属性
解决方案
一、无需自定义代码,用Keycloak内置的Script Mapper即可实现
Keycloak自带的Script Mapper支持在UI中编写Groovy脚本处理复杂属性映射,完全能搞定嵌套数组解析、多值属性生成的需求,具体步骤如下:
进入映射器配置页
- 若要先将解析后的属性存入Keycloak用户属性再写入JWT:进入对应「身份提供商」→「Mappers」页面,添加新映射器;
- 若直接将解析结果写入JWT(不存储到用户属性):进入目标「客户端」→「Mappers」页面,添加新映射器。
创建Script Mapper
- 选择映射器类型为「Script Mapper」;
- 填写名称(如
Nested Array Parser),设置Token Claim Name(即JWT中返回的字段名); - 在「Script」编辑框中编写解析逻辑,示例脚本如下(根据你的实际嵌套结构调整):
// 从IDP返回的userInfo中获取嵌套数组(替换为实际字段名) def userInfo = idpContext.getUserInfo() def nestedArray = userInfo.get("yourNestedArrayField") // 提取目标属性值 def extractedValues = [] nestedArray.each { item -> // 按实际字段名提取attributeIWant1/2/3 if (item.attributeIWant1) extractedValues.add(item.attributeIWant1) if (item.attributeIWant2) extractedValues.add(item.attributeIWant2) if (item.attributeIWant3) extractedValues.add(item.attributeIWant3) } // 方案1:将多值属性存入Keycloak用户(用##分隔,符合Keycloak多值属性存储规范) user.setAttribute("yourMultiValueAttr", extractedValues.join("##")) // 方案2:直接返回数组到JWT(客户端会收到数组类型的Claim) return extractedValues
配置额外选项
- 根据需求设置「Claim JSON Type」(如
JSON Array),确保JWT返回正确类型; - 勾选「Add to ID token」「Add to access token」等选项,控制属性写入的令牌类型。
- 根据需求设置「Claim JSON Type」(如
二、关于多值属性的分隔符
Keycloak存储用户多值属性时,确实默认使用##作为分隔符,但如果是直接写入JWT,建议返回数组类型(上述方案2),更符合JWT规范;若客户端明确需要分隔符格式的字符串,再用join("##")处理即可。
三、什么时候需要自定义代码?
只有当映射逻辑极度复杂(比如涉及外部API调用、复杂加密等),Script Mapper无法满足时,才需要编写Java自定义映射器(打包成JAR部署到Keycloak的providers目录)。但针对你当前的嵌套数组解析需求,Script Mapper完全足够。
内容的提问来源于stack exchange,提问作者Mir
相关产品推荐
相关产品推荐

