如何在Keycloak实例中查询分配给指定角色的权限
Keycloak 角色权限获取解决方案
核心逻辑说明
Keycloak 中分配给角色的权限分为三类,可通过 Keycloak Admin Client 原生API直接获取,无需额外调用自定义接口:
- 领域级权限:即分配给当前角色的上级领域角色
- 客户端级权限:即分配给当前角色的指定客户端下的角色
- 授权服务权限:开启客户端授权功能后,绑定到该角色的自定义资源/Scope权限
代码实现
1. 新增角色权限查询接口
在你现有的RolesController中新增如下接口即可实现查询:
// 按角色ID查询分配给该角色的所有权限 @GetMapping("/{roleId}/permissions") public ResponseEntity<Map<String, Object>> getRolePermissions(@PathVariable String roleId) { RealmResource dashingRealm = keycloak.realm("dashing-data"); RoleResource roleResource; // 校验角色是否存在 try { roleResource = dashingRealm.rolesById().get(roleId); // 触发查询判断角色是否存在 roleResource.toRepresentation(); } catch (NotFoundException e) { return new ResponseEntity<>(Map.of("msg", "目标角色不存在"), HttpStatus.NOT_FOUND); } Map<String, Object> result = new HashMap<>(); // 获取领域级权限 Set<RoleRepresentation> realmPermissions = roleResource.getRealmRoleMappings(); result.put("realmLevelPermissions", realmPermissions); // 获取所有客户端级权限 List<ClientRepresentation> allClients = dashingRealm.clients().findAll(); Map<String, Set<RoleRepresentation>> clientPermissionMap = new HashMap<>(); for (ClientRepresentation client : allClients) { Set<RoleRepresentation> clientRoles = roleResource.getClientRoleMappings(client.getId()); if (!clientRoles.isEmpty()) { clientPermissionMap.put(client.getClientId(), clientRoles); } } result.put("clientLevelPermissions", clientPermissionMap); // 若需要查询授权服务下绑定的权限,取消注释以下代码,替换为你开启授权的客户端ID /* String authClientId = "your_client_id"; ClientRepresentation authClient = dashingRealm.clients().findByClientId(authClientId).get(0); AuthzResource authz = dashingRealm.clients().get(authClient.getId()).authorization(); // 查询所有资源类权限绑定当前角色的条目 List<PermissionRepresentation> resourcePermissions = authz.permissions().resource().findAll().stream() .filter(perm -> perm.getRoles() != null && perm.getRoles().contains(roleResource.toRepresentation().getName())) .collect(Collectors.toList()); // 查询所有Scope类权限绑定当前角色的条目 List<PermissionRepresentation> scopePermissions = authz.permissions().scope().findAll().stream() .filter(perm -> perm.getRoles() != null && perm.getRoles().contains(roleResource.toRepresentation().getName())) .collect(Collectors.toList()); result.put("authzResourcePermissions", resourcePermissions); result.put("authzScopePermissions", scopePermissions); */ return new ResponseEntity<>(result, HttpStatus.OK); }
2. 修复现有删除接口的BUG
你现有的删除接口逻辑存在错误,永远不会执行实际删除操作也不会返回不存在的提示,修复后代码如下:
@DeleteMapping("/{id}") public ResponseEntity<String> deleteRole(@PathVariable String id){ try { // 先校验角色是否存在 keycloak.realm("dashing-data").rolesById().get(id).toRepresentation(); // 执行删除 keycloak.realm("dashing-data").rolesById().deleteRole(id); return new ResponseEntity<>("Role successfully deleted!", HttpStatus.OK); } catch (NotFoundException e) { return new ResponseEntity<>("Could not find the role!", HttpStatus.NOT_FOUND); } }
注意事项
- 若需要查询授权服务权限,需先在Keycloak后台对应客户端的
Authorization标签页开启授权功能 - 操作的admin账号需要有对应领域的
view-realm、view-clients、view-authorization权限,默认master realm的admin账号已具备全部权限
内容的提问来源于stack exchange,提问作者Lacatin
相关产品推荐
相关产品推荐

