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

Spring Boot集成Keycloak RBAC遇403 Forbidden问题求助

问题排查与解决方案

核心原因:Keycloak JWT角色未映射为Spring Security权限

Spring Security OAuth2资源服务器默认不会自动解析Keycloak JWT里的realm_access.roles或resource_access.<client-id>.roles字段作为权限(Authority),这是导致403禁止访问的关键问题。

第一步:确认JWT中的角色位置

先通过在线JWT解析工具打开你的Bearer令牌,查看角色所在的字段:

  • 若为Realm级角色,角色列表会在realm_access.roles数组内
  • 若为客户端级角色,角色列表会在resource_access.myclient.roles数组内(myclient是你的客户端ID)

第二步:添加JWT权限转换器

需要自定义JwtAuthenticationConverter,把Keycloak JWT中的角色字段转换成Spring Security能识别的权限。

修改SecurityConfig,新增以下Bean:

import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;

// ... 原有代码保持不变

@Bean
public JwtAuthenticationConverter jwtAuthenticationConverter() {
    JwtGrantedAuthoritiesConverter grantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
    // 针对Realm角色的配置,若为客户端角色则修改为resource_access.myclient.roles
    grantedAuthoritiesConverter.setAuthoritiesClaimName("realm_access.roles");
    // 如果后续要用hasRole("myrole")校验,可开启前缀(hasAuthority不需要)
    // grantedAuthoritiesConverter.setAuthorityPrefix("ROLE_");

    JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
    jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(grantedAuthoritiesConverter);
    return jwtAuthenticationConverter;
}

然后在资源服务器配置中引用这个转换器:

@Bean
public SecurityFilterChain resourceServerFilterChain(HttpSecurity http) throws Exception {
    http.authorizeHttpRequests(authorize -> authorize.anyRequest().hasAuthority("myrole"));
    http.oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> jwt.jwtAuthenticationConverter(jwtAuthenticationConverter())));
    return http.build();
}

第三步:清理无效配置

spring.security.oauth2.client.provider.keycloak.use-resource-role-mappings=true这个配置只在Spring Boot作为OAuth2客户端(登录流程)时生效,资源服务器模式下没用,可以从application.properties里删掉。

第四步:确认Keycloak角色分配

  • 确保目标用户确实被分配了myrole:
    • Realm角色:在Keycloak控制台的Realm Roles找到myrole,进入Users标签页验证用户已添加
    • 客户端角色:进入Clients -> myclient -> Roles确认myrole存在,再到Users -> 目标用户 -> Role Mappings -> Client Roles选择myclient,检查myrole已分配

第五步:其他检查项

  • 确认application.properties里的spring.security.oauth2.resourceserver.jwt.issuer-uri正确指向Keycloak Realm地址(http://localhost:8080/realms/myrealm),Spring会自动获取公钥验证JWT签名
  • 确保Postman使用的Bearer令牌是针对该Realm和客户端生成的,且未过期

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 09:59:52