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

Spring Boot资源服务器RBAC失效,访问端点返回403求助

问题分析与解决方案

问题根源有两点:

  1. 你定义的自定义权限/认证转换器并未被Spring Security的OAuth2资源服务器实际启用,导致权限解析逻辑未生效
  2. Spring Security的hasRole方法会自动为角色名称添加ROLE_前缀,但你的权限转换后是原始角色名(如USER),两者无法匹配,触发403禁止访问

修复步骤

1. 启用自定义认证转换器

修改SecurityConfiguration中的filterChain方法,将自定义的Jwt2AuthenticationConverter配置到OAuth2资源服务器的JWT逻辑中:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http, Jwt2AuthenticationConverter authenticationConverter) throws Exception {
    http
        .cors().disable()
        .csrf().disable()
        .authorizeHttpRequests(auth -> auth
            .requestMatchers("/workstations").hasRole("USER")
            .anyRequest().authenticated()
        )
        .oauth2ResourceServer(jwt -> jwt
            .jwtAuthenticationConverter(authenticationConverter) // 配置自定义转换器
        )
        .sessionManagement(session -> session
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        );

    return http.build();
}

2. 解决角色前缀匹配问题(二选一)

方案A:为转换后的角色添加ROLE_前缀

修改authoritiesConverter方法,在生成权限对象时自动添加前缀,适配hasRole的规则:

@SuppressWarnings("unchecked")
@Bean
public Jwt2AuthoritiesConverter authoritiesConverter() {
    return jwt -> {
        final var realmAccess = (Map<String, Object>) jwt.getClaims().getOrDefault("realm_access", Map.of());
        final var realmRoles = (Collection<String>) realmAccess.getOrDefault("roles", List.of());

        // 为角色添加ROLE_前缀
        return realmRoles.stream()
            .map(role -> new SimpleGrantedAuthority("ROLE_" + role))
            .toList();
    };
}

方案B:改用hasAuthority替代hasRole

如果不想修改角色前缀,直接修改权限校验规则,使用hasAuthority匹配原始角色名称:

.authorizeHttpRequests(auth -> auth
    .requestMatchers("/workstations").hasAuthority("USER") // 替换hasRole为hasAuthority
    .anyRequest().authenticated()
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 11:46:02