如何通过Spring Boot应用在Keycloak中添加自定义用户属性
Keycloak通过UserRepresentation添加用户自定义属性实现方案
org.keycloak.representations.idm.UserRepresentation 本身原生支持自定义属性存储,不存在“不支持直接添加”的问题——只是它没有为每个自定义属性单独封装set/get方法,所有非内置属性统一通过类内的attributes字段承载,很多开发者没注意到这个字段才会误以为能力缺失。
具体实现步骤
- 确保项目中引入的Keycloak Admin Client依赖版本和部署的Keycloak服务版本一致,避免序列化兼容问题
- 创建/更新用户对象时,直接向
attributes字段(类型为Map<String, List<String>>)填充自定义属性即可 - 调用Keycloak Admin接口完成用户创建/更新,自定义属性会自动同步到Keycloak用户数据中
新增用户时添加自定义属性代码示例
import org.keycloak.representations.idm.UserRepresentation; import java.util.*; // 构建用户基础信息 UserRepresentation newUser = new UserRepresentation(); newUser.setUsername("zhangsan"); newUser.setFirstName("三"); newUser.setLastName("张"); newUser.setEmail("zhangsan@example.com"); newUser.setEnabled(true); // 填充自定义属性 注意value必须是List<String>类型 Map<String, List<String>> customAttrs = new HashMap<>(); customAttrs.put("employee_id", Collections.singletonList("E2024001")); customAttrs.put("department", Collections.singletonList("后端开发组")); customAttrs.put("office_location", Collections.singletonList("北京海淀职场")); newUser.setAttributes(customAttrs); // 调用Keycloak Admin接口创建用户 keycloak.realm("你的业务realm名称") .users() .create(newUser);
已存在用户更新自定义属性注意事项
给已有用户追加/修改自定义属性时,不能只传你要新增的属性直接调用update,会覆盖掉用户之前存储的所有自定义属性,正确写法如下:
String targetUserId = "用户在Keycloak中的唯一ID"; // 先拉取用户当前的完整信息 UserRepresentation existUser = keycloak.realm("你的业务realm名称") .users() .get(targetUserId) .toRepresentation(); // 取出已有属性,为空则初始化 Map<String, List<String>> existAttrs = existUser.getAttributes() == null ? new HashMap<>() : new HashMap<>(existUser.getAttributes()); // 追加/修改自定义属性 existAttrs.put("last_login_ip", Collections.singletonList("192.168.1.100")); existUser.setAttributes(existAttrs); // 提交更新 keycloak.realm("你的业务realm名称") .users() .get(targetUserId) .update(existUser);
常见踩坑点
- 自定义属性的value必须是
List<String>类型,哪怕属性是单值,也要用Collections.singletonList()包装成列表,否则会出现序列化失败、属性丢失的问题 - 如果需要把自定义属性放到JWT令牌(ID Token/Access Token)中返回给前端/下游服务,需要登录Keycloak管理后台,在对应业务客户端的Mappers配置中新增
User Attribute类型的映射器,填写定义的自定义属性名,勾选需要加入的令牌范围即可 - 自定义属性名区分大小写,配置Mapper和代码填充时要保持完全一致,否则会出现属性取不到值的问题
内容的提问来源于stack exchange,提问作者Israr ul haq
相关产品推荐
相关产品推荐

