一篇学会java调用Keycloak Admin-cli User和Group Api

Posted 浦江之猿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一篇学会java调用Keycloak Admin-cli User和Group Api相关的知识,希望对你有一定的参考价值。

Keycloak admin-cli Api 可以方便的用于管理用户,组,角色等数据。本博客总结了一下如何管理用户和组的信息,学习的最初来源keycloak官方文档

XXXResource

从官方文档中可以发现,有几组这样的类 UserResource/UsersResource, RoleResource/RolesResource, GroupResource/GroupsResource等. 这些类在keycloak admin-cli api 扮演着controller的角色,因此通过它们可以对相应的资源进行CRUD的操作。以UserResource/UsersResource为例, UserResouce 用于某一具体user的操作,而UsersResource用于user集合的操作,例如根据id修改user的信息,就需要使用UserResource,而获取一组user则需要使用UsersResource.

XXXRepresentation

与XXXResource一样, 存在这样一些类UserRepresentation, RoleRepresentation, GroupRepresentation等. 它们扮演着model的角色,通过它们可以将我们需要的信息呈现出来。

CRUD operation

CRUD之前, keycloak admin-cli 必须配进整个环境中,可以之前的博文

User CRUD

在CRUD之前,必须先通过keycloak的实例拿到user 的controller,也就是所谓的UsersResource. 注意: keycloak的实例可以以bean方式注入到spring窗口中,可以参考此文

UsersResource usersResource = keycloak.realm(realm).users();

Create User

//创建user model
UserRepresentation userRepresentation = new UserRepresentation();
userRepresentation.setUsername("po");
userRepresentation.setEnabled(true);
//使用controller(UsersResource) 调用创建user的api
Response response = usersResource.create(userRepresentation )

Retrieve user

keycloak admin-cli api 提供了多种方式获取user,这里仅提供一种,详细的可以参考其官方文档

//获取 10 users
List<UserRepresentation> userList = usersResource.list(0, 10);
// 过滤得到状态为enabled用户
userList.stream().filter(user -> user.isEnabled().booleanValue());

Update User

// 先根据user id 从user 集合中获取此user的user resource
UserResource userResource = usersResource.get(id);
// 获取此user的model
UserRepresentation userPresentation = userResource.toRepresentation();
// 设置新值
userPresentation.setLastName(“lastName”);
// 调用 update api
userResource.update(userPresentation);

Delete User

这里需要注意一下,因为是从某一集合中删除user,所以不需要将user拿出来对其操作,故直接使用UsersResource即可。

Response response = usersResource.delete(userId);

Group CRUD

与User的操作一样,在操作group前,group的controller(GroupResource/GroupsResource)也需要通过keycloak的实例获取。
注意: keycloak的实例可以以bean方式注入到spring窗口中,可以参考此文

GroupsResource groupsResource = keycloak.realm(realm).groups()

Create Group

//创建group model
GroupRepresentation groupRepresentation = new GroupRepresentation();
// 这里一定要注意,创建组时只需要设置一个组名就可以了
groupRepresentation.setName("name");
// 使用controller(GroupsResource)调用 add api (注意这里是add,与user不一样,user使用的是create)
groupsResource.add(groupRepresentation);

Retrieve Group

//获取所有的组
 List<GroupRepresentation> groupList= groupsResource.groups();
// 根据组名过滤需要的组
 groupList = groupList.stream().filter(g -> g.getName().equals(groupName)).collect(Collectors.toList());

注意: keycloak貌似没有提供根据组名获取组的api,必须要先获取所有的组,再对其过滤,这里有点小扯,不知道是自己没有发现到,还是官方就是如此,如果有大神发现了此api,欢迎指正。PS:我参考的文档版本是17

Update Group Name

这里和update user 一样,需要先获取"GroupResource" (不是 GroupsResource)。这里又有点扯了,必须要根据id去获取"GroupResource" ( **不是根据名字去获取 ** ),而组id需要先根据组名获取到组model,之后才能获取到id,真的好扯,这一块如果我错了,希望有大神能指点下。总之,获取GroupResouce的流程如下:getAllGroups->getGroupPresentationByName->getGroupId->getGroupReourceById.

//这一段承接上文Retrieve Group
GroupRepresentation groupRepresentation= groupList.get(0); 
String groupId = groupRepresentation.getId();
GroupResource groupResource = keycloak.realm(realm).groups().group(groupId );
//更新组名
groupRepresentation.setName("newName");
groupResource.update(groupRepresentation);

Delete Group

删除group跟删除user又不一样了,删除user使用的是UsesResource,而删除组用到的确实是GroupResource, 真心搞不懂,估计keycloak这一块不是同一个人开发的。当然,获取GroupResource的方式跟Update Group 一致,这里不再赘述。

GroupRepresentation groupRepresentation= groupList.get(0); 
String groupId = groupRepresentation.getId();
GroupResource groupResource = keycloak.realm(realm).groups().group(groupId );
groupResource.remove();

Create Group Attributes

Group attributes 是以map的形式存在的,所以针对一个新组需要先创建一个map,反之先获取到此group的map即可。这里以一个存在的group为例。

Map<String, List<String>> attributes = null;
//根据组名获取group, 方法"getBroupByName"的逻辑参考===Retrieve Group===
GroupRepresentation groupRepresentation = getGroupByName(grpName).get(0);
//根据 group id 获取groupResource
GroupResource groupResource = keycloak.realm(realm).groups().group(groupRepresentation.getId());
attributes = groupRepresentation.getAttributes();
if (null == attributes) 
    attributes = new HashMap<>();

attributes.put(key, values);
groupRepresentation.setAttributes(attributes);
//创建好新的属性,调用update api
groupResource.update(groupRepresentation);

Retrieve Group Attributes

keycloak的数据结构设计的很巧妙,组的属性可见性取决于传入的参数,默认是隐藏的,所以为了拿到属性,调用api应该传入false.
//获取带属性的组model,这里一定要注意第4个参数必须是false,不然后attributes永远是null。

 List<GroupRepresentation> groups = keycloak.realm(realm).groups().groups(null, 0, Integer.MAX_VALUE,false);
//这里的逻辑省略了,主要是为了获取某一具体的group model.
...
//获取某一具体组的所有属性
Map<String, List<String>>  attributes = groupRepresentation.getAttributes();
//根据key值获取某一具体的属性
List<String> attribute = attributes.get(key);

Update Group Attributes

既然是更新组属性,所以拿组的时候一定要带有属性,可以参考 Retrieve Group Attributes,然后根据key来更新组属性。这里有两种情况, 一种是添加(追加)一个新属性,一种是更新(替换)已有的属性。

//根据组名获取带有属性的组
// 方法"getBroupByName"的逻辑参考===Retrieve Group===
GroupRepresentation groupRepresentation = getGroupByName(grpName).get(0);
GroupResource groupResource = keycloak.realm(realm).groups().group(groupRepresentation.getId());
Map<String, List<String>> attributes = groupRepresentation.getAttributes();
//append是一个布尔值. Ture: 追加. Fasle: 替换 
List<String> updateList = append ? attributes.get(key) : new ArrayList<>();
updateList.add(values);
attributes.put(key, updateList);
groupRepresentation.setAttributes(attributes);
//设置好属性后, 调用update方法
groupResource.update(groupRepresentation);

Delete Group Attributes

既然是删除组属性,所以拿组的时候一定要带有属性,可以参考 Retrieve Group Attributes,然后根据key值删除。

//根据组名获取带有属性的组
// 方法"getBroupByName"的逻辑参考===Retrieve Group===
GroupRepresentation groupRepresentation = getGroupByName(grpName).get(0);
GroupResource groupResource = keycloak.realm(realm).groups().group(groupRepresentation.getId());
Map<String, List<String>>  attributes = groupRepresentation.getAttributes();
//删除属性
attributes.remove(key);
groupRepresentation.setAttributes(attributes);
//删除之后,调用update api
groupResource.update(groupRepresentation);

Put an user to Group

将user添加到某个组里通过UserResource(不是UsersResource)

UserResource userResource = keycloak.realm(realm).users().get(userId);
//这里传入的是组id
userResource.joinGroup(groupId);

Remove an user from Group

将user从某个组里移出也是通过UserResource(不是UsersResource)

UserResource userResource = keycloak.realm(realm).users().get(userId);
//这里传入的是组id
userResource.leaveGroup(groupId);

小结

到这,关于keycloak Admin-cli对user 和group的操作就介绍完了,其中对于组的操作感觉有些地方不太符合编程逻辑,如有大神发现更好的方法,望指点,在此先谢过。最后,希望本文能帮助大家,祝大家在IT之路上少走弯路,一路绿灯不堵车,测试一性通过,bug秒解!

以上是关于一篇学会java调用Keycloak Admin-cli User和Group Api的主要内容,如果未能解决你的问题,请参考以下文章

使用 Keycloak Admin Java API 向用户添加角色

如何在不使用 rest admin api 的情况下以编程方式(java)更新 keycloak 的用户详细信息?

无法使用 Keycloak admin api 设置用户凭据

通过 keycloak admin 客户端在 keycloak 中创建用户返回 IllegalArgumentException

Springboot 集成keycloak admin-cli api

如何在 keycloak 中调用 create user api 后获取 userId?