Spring Boot整合Keycloak时GrantedAuthority始终为空如何解决
问题原因
你遇到的权限列表为空问题是Keycloak与Spring Security整合时两个常见配置遗漏导致的:
- 默认未开启realm级角色解析:Keycloak官方Spring适配器默认只会提取当前客户端(对应你配置的
keycloak.resource参数)下的角色,JWT中realm_access下的全局角色不会被自动解析到GrantedAuthority列表中 - 安全配置类未使用专用注解:你当前使用普通
@Configuration+@EnableWebSecurity组合,没有使用Keycloak提供的专用组合注解,会导致部分Keycloak核心配置加载不完整
解决步骤
第一步:替换安全配置类注解
把SecurityConfiguration类上的注解替换为@KeycloakConfiguration,无需再单独加@Configuration和@EnableWebSecurity:
@KeycloakConfiguration @EnableGlobalMethodSecurity(jsr250Enabled = true) public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter { // 原有代码保持不变 }
第二步:添加角色解析配置
在你的application.properties/application.yml中添加如下配置,允许适配器读取realm级别的角色:
properties格式:
keycloak.use-resource-role-mappings=false
yml格式:
keycloak: use-resource-role-mappings: false
如果你的角色是配置在当前客户端下而非realm全局,将上面的配置值改为true即可
(可选)自定义角色提取逻辑
如果上述配置仍然无法读取角色,可以重写KeycloakAuthenticationProvider的角色提取方法,手动从JWT的realm_access字段解析角色:
首先自定义认证Provider:
public class CustomKeycloakAuthenticationProvider extends KeycloakAuthenticationProvider { @Override protected Collection<? extends GrantedAuthority> extractAuthorities(AccessToken accessToken) { List<GrantedAuthority> authorities = new ArrayList<>(super.extractAuthorities(accessToken)); // 手动提取realm全局角色 AccessToken.Access realmAccess = accessToken.getRealmAccess(); if (realmAccess != null) { for (String role : realmAccess.getRoles()) { authorities.add(new SimpleGrantedAuthority("ROLE_" + role)); } } return authorities; } }
然后替换配置类中的认证Provider配置:
@Autowired public void configureGlobal(final AuthenticationManagerBuilder auth) throws Exception { SimpleAuthorityMapper grantedAuthorityMapper = new SimpleAuthorityMapper(); grantedAuthorityMapper.setPrefix("ROLE_"); CustomKeycloakAuthenticationProvider keycloakAuthenticationProvider = new CustomKeycloakAuthenticationProvider(); keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(grantedAuthorityMapper); auth.authenticationProvider(keycloakAuthenticationProvider); }
配置完成后重启服务即可正常读取JWT中的角色信息,@RolesAllowed注解会正常生效。
内容的提问来源于stack exchange,提问作者DrTeeth
相关产品推荐
相关产品推荐

