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

如何在Spring Security中获取Keycloak客户端角色用于权限校验

方案1:使用Keycloak官方Spring Boot适配器(适合Spring Boot 2.6及以下版本)

第一步:修改application.yml配置

添加核心配置开关use-resource-role-mappings,开启后适配器会自动将对应client下的角色加载到Spring Security的权限列表中:

keycloak:
  auth-server-url: http://你的Keycloak服务地址/auth
  realm: 你的Realm名称
  resource: myproject # 替换为你的实际client id,和JWT中resource_access的key保持一致
  use-resource-role-mappings: true # 开启client角色映射的核心配置
  bearer-only: true # 纯后端资源服务可开启该配置

第二步:调整权限校验规则

配置完成后原有校验逻辑可直接生效,若不需要Spring Security默认的ROLE_前缀,也可以改用hasAuthority精准匹配角色名:

private void configureMyRole(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        // 两种写法二选一,和权限映射的前缀规则对应即可
        // .antMatchers("/api/**").hasAnyRole("MyClientRole")
        .antMatchers("/api/**").hasAnyAuthority("MyClientRole")
        .anyRequest().permitAll();
}

方案2:使用Spring Security原生Oauth2资源服务器(Spring Boot 2.7+推荐方案,Keycloak官方已停止维护独立适配器)

Spring Security 5+原生支持JWT解析,只需要自定义权限映射逻辑即可提取client角色,不需要额外引入Keycloak适配器。

第一步:自定义权限映射器

实现JWT权限转换逻辑,同时支持提取Realm角色和Client角色:

import org.springframework.core.convert.converter.Converter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.jwt.Jwt;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

public class KeycloakGrantedAuthoritiesConverter implements Converter<Jwt, Collection<GrantedAuthority>> {
    // 替换为你的实际client id,和JWT中resource_access的key保持一致
    private static final String CLIENT_ID = "myproject";

    @Override
    public Collection<GrantedAuthority> convert(Jwt jwt) {
        List<GrantedAuthority> authorities = new ArrayList<>();
        // 提取Realm角色(不需要可删除该段逻辑)
        Map<String, Object> realmAccess = jwt.getClaim("realm_access");
        if (realmAccess != null && realmAccess.containsKey("roles")) {
            ((List<String>) realmAccess.get("roles")).forEach(role -> 
                authorities.add(new SimpleGrantedAuthority(role))
            );
        }
        // 提取Client角色
        Map<String, Object> resourceAccess = jwt.getClaim("resource_access");
        if (resourceAccess != null && resourceAccess.containsKey(CLIENT_ID)) {
            Map<String, Object> clientResource = (Map<String, Object>) resourceAccess.get(CLIENT_ID);
            if (clientResource.containsKey("roles")) {
                ((List<String>) clientResource.get("roles")).forEach(role -> 
                    authorities.add(new SimpleGrantedAuthority(role))
                );
            }
        }
        return authorities;
    }
}

第二步:配置JWT解析器

将自定义转换器注册到Spring Security的JWT解析流程中:

@Bean
public JwtAuthenticationConverter jwtAuthenticationConverter() {
    JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
    converter.setJwtGrantedAuthoritiesConverter(new KeycloakGrantedAuthoritiesConverter());
    return converter;
}

private void configureMyRole(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        .antMatchers("/api/**").hasAnyAuthority("MyClientRole")
        .anyRequest().permitAll()
        .and()
        // 配置原生JWT资源服务器
        .oauth2ResourceServer()
        .jwt()
        .jwtAuthenticationConverter(jwtAuthenticationConverter());
}

常见注意事项
  • 配置中的clientId必须和JWT中resource_access下的客户端key完全一致,大小写敏感
  • 若使用hasRole做校验,Spring Security会自动匹配带ROLE_前缀的权限项,可根据需求在映射角色时添加此前缀,或直接使用hasAuthority精准匹配角色名
  • 自定义映射逻辑可灵活控制同时保留Realm角色和Client角色,或者只保留其中一种

内容的提问来源于stack exchange,提问作者deevelop

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 14:36:04