Keycloak Admin Client Spring用户删除异常:列表仅100条且角色为空
解决Keycloak用户列表分页与角色获取问题
问题1:用户列表仅返回100条
Keycloak的users().list()方法默认采用分页机制,每页最多返回100条数据。要获取全部用户,必须通过循环分页查询的方式,直到没有新结果返回为止。
问题2:user.getRealmRoles()始终为null
通过list()方法获取的UserRepresentation对象默认不会携带角色信息,需要单独调用Keycloak的角色API,针对每个用户查询其realm角色。
修改后的完整代码
public void deleteWhereNotIn(List<String> keep) { int firstResult = 0; final int maxResults = 100; List<UserRepresentation> users; // 循环分页拉取所有用户 do { users = keycloak.realm(realm).users().list(firstResult, maxResults); List<String> remove = new ArrayList<>(); for (UserRepresentation user : users) { // 单独查询用户的realm角色 List<RoleRepresentation> realmRoles = keycloak.realm(realm) .users().get(user.getId()) .roles().realmLevel().list(); // 跳过拥有ADMIN角色的用户 if (realmRoles != null && realmRoles.stream().anyMatch(role -> role.getName().equals("ADMIN"))) { continue; } // 不在保留列表内的用户加入删除队列 if (keep.stream().noneMatch(uid -> uid.equals(user.getId()))) { remove.add(user.getId()); } } // 执行删除操作 for (String uid : remove) { delete(uid); } firstResult += maxResults; } while (!users.isEmpty()); }
补充说明
- 分页查询时,每次从
firstResult位置开始拉取maxResults条数据,直到返回的用户列表为空,代表所有用户已处理完毕。 - 获取角色时使用
roles().realmLevel().list(),并通过role.getName()判断角色名称,避免因RoleRepresentation对象的equals逻辑不匹配导致判断失效。 - 若担心频繁API调用的性能问题,可以尝试用Keycloak的查询API预先筛选非ADMIN用户(例如
users().search()配合角色参数),减少不必要的角色查询次数。
内容的提问来源于stack exchange,提问作者galalem
相关产品推荐
相关产品推荐

