You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Keycloak权限自定义UI:Spring Boot Vaadin应用权限获取咨询

如何从Keycloak获取角色关联的权限/策略列表

嘿,很高兴看到你已经成功从Keycloak拿到用户关联的角色了!针对你的问题,答案是肯定的——你完全可以获取到角色对应的权限或策略,这里有几种实用的方案,你可以根据自己的场景选择:

方案一:通过Keycloak Admin API查询

Keycloak的默认JWT Token里不会包含角色对应的权限细节(为了保持Token轻量化),所以你可以调用Admin API来实时查询角色关联的权限。

步骤说明:

  1. 首先需要获取Keycloak Admin的访问令牌(你需要提前在Keycloak控制台配置一个有Admin权限的客户端);
  2. 调用对应的Admin API端点查询角色权限;
  3. 解析返回的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中获取权限。

配置步骤:

  1. 登录Keycloak控制台,进入你的目标Realm;
  2. 找到你的客户端(也就是代码里的myresource),切换到「Mappers」标签页;
  3. 点击「Create」新建一个Mapper,类型选择「Script Mapper」;
  4. 在「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);
    
  5. 保存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库来查询权限。

步骤说明:

  1. 在Spring Boot项目中引入依赖:
    <dependency>
        <groupId>org.keycloak</groupId>
        <artifactId>keycloak-authz-client</artifactId>
        <version>你的Keycloak版本</version>
    </dependency>
    
  2. 在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"
        }
    }
    
  3. 在代码中查询权限:
    // 初始化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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:56:23