基于Keycloak权限自定义UI:Spring Boot Vaadin应用权限获取咨询
如何从Keycloak获取角色关联的权限/策略列表
嘿,很高兴看到你已经成功从Keycloak拿到用户关联的角色了!针对你的问题,答案是肯定的——你完全可以获取到角色对应的权限或策略,这里有几种实用的方案,你可以根据自己的场景选择:
方案一:通过Keycloak Admin API查询
Keycloak的默认JWT Token里不会包含角色对应的权限细节(为了保持Token轻量化),所以你可以调用Admin API来实时查询角色关联的权限。
步骤说明:
- 首先需要获取Keycloak Admin的访问令牌(你需要提前在Keycloak控制台配置一个有Admin权限的客户端);
- 调用对应的Admin API端点查询角色权限;
- 解析返回的JSON数据得到权限列表。
代码示例(Spring Boot环境):
// 先实现获取Admin Token的逻辑(示例,实际要根据你的配置调整) private String getAdminToken() { String tokenUrl = "http://your-keycloak-server/auth/realms/master/protocol/openid-connect/token"; MultiValueMap<String, String> params = new LinkedMultiValueMap<>(); params.add("grant_type", "client_credentials"); params.add("client_id", "admin-cli"); // 默认的Admin客户端ID params.add("client_secret", "your-admin-client-secret"); RestTemplate restTemplate = new RestTemplate(); ResponseEntity<Map> response = restTemplate.postForEntity(tokenUrl, params, Map.class); return (String) response.getBody().get("access_token"); } // 查询指定角色的权限 public Set<String> getRolePermissions(String roleName) { String adminToken = getAdminToken(); String realm = "your-realm-name"; String apiUrl = String.format("http://your-keycloak-server/auth/admin/realms/%s/roles/%s/permissions", realm, roleName); HttpHeaders headers = new HttpHeaders(); headers.setBearerAuth(adminToken); HttpEntity<Void> entity = new HttpEntity<>(headers); RestTemplate restTemplate = new RestTemplate(); ResponseEntity<List<Map>> response = restTemplate.exchange(apiUrl, HttpMethod.GET, entity, new ParameterizedTypeReference<List<Map>>() {}); // 解析返回的权限数据,这里简单提取权限名称,实际根据返回结构调整 Set<String> permissions = new HashSet<>(); for (Map<String, Object> perm : response.getBody()) { permissions.add((String) perm.get("name")); } return permissions; }
注意事项:
- 确保你的应用有Keycloak Admin的权限,并且妥善管理Admin令牌的有效期和安全性;
- 如果权限不频繁变化,可以考虑缓存查询结果,减少API调用次数。
方案二:通过Protocol Mapper把权限嵌入JWT Token
如果你不想每次都调用Admin API,更高效的方式是通过Keycloak的Protocol Mapper,把角色对应的权限直接添加到用户登录后的JWT Token里,这样你就能像读取角色一样直接从Token中获取权限。
配置步骤:
- 登录Keycloak控制台,进入你的目标Realm;
- 找到你的客户端(也就是代码里的
myresource),切换到「Mappers」标签页; - 点击「Create」新建一个Mapper,类型选择「Script Mapper」;
- 在「Script」字段中编写逻辑,查询当前用户角色对应的权限并添加到Token的自定义字段中,比如:
// 示例脚本:获取当前用户所有角色的权限,添加到permissions字段 var permissions = []; var realm = session.getContext().getRealm(); var user = session.getContext().getUser(); user.getRoleMappings().forEach(function(role) { var rolePermissions = realm.getAuthorizationManager().getPermissions(role); rolePermissions.forEach(function(perm) { permissions.push(perm.getName()); }); }); token.setOtherClaims("permissions", permissions); - 保存Mapper后,让用户重新登录,此时Token里就会包含
permissions字段。
代码中读取权限:
KeycloakPrincipal principal = (KeycloakPrincipal) VaadinService.getCurrentRequest().getUserPrincipal(); // 从Token的自定义Claims中读取权限 List<String> permissions = (List<String>) principal.getKeycloakSecurityContext().getToken().getOtherClaims().get("permissions");
注意事项:
- 确保Keycloak开启了脚本支持(默认可能需要在
standalone.xml中配置开启); - 脚本逻辑要注意性能,避免复杂查询拖慢登录流程。
方案三:使用Keycloak Authorization Client库(适合精细权限场景)
如果你在Keycloak中使用了Authorization Service(也就是基于资源、范围的精细权限管理),可以直接用官方的Authorization Client库来查询权限。
步骤说明:
- 在Spring Boot项目中引入依赖:
<dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-authz-client</artifactId> <version>你的Keycloak版本</version> </dependency> - 在
src/main/resources下添加keycloak.json配置文件(或者通过Spring配置类初始化):{ "realm": "your-realm-name", "auth-server-url": "http://your-keycloak-server/auth", "resource": "myresource", "credentials": { "secret": "your-client-secret" } } - 在代码中查询权限:
// 初始化AuthorizationClient AuthorizationClient authorizationClient = AuthorizationClient.create(); // 构建授权请求,指定要查询的资源 AuthorizationRequest request = new AuthorizationRequest(); request.addResource("myresource"); // 获取授权响应,包含用户的权限列表 AuthorizationResponse response = authorizationClient.authorize(request); Set<Permission> permissions = response.getPermissions(); // 遍历权限获取详细信息 for (Permission perm : permissions) { System.out.println("权限资源:" + perm.getResourceName()); System.out.println("权限范围:" + perm.getScopeName()); }
注意事项:
- 这种方式适合已经配置了Keycloak Authorization Policy的场景,能获取到更精细的权限信息(比如资源、范围);
- 需要确保你的客户端在Keycloak中开启了Authorization支持。
内容的提问来源于stack exchange,提问作者user2183185
相关产品推荐
相关产品推荐

