Spring Boot资源服务器RBAC失效,访问端点返回403求助
问题分析与解决方案
问题根源有两点:
- 你定义的自定义权限/认证转换器并未被Spring Security的OAuth2资源服务器实际启用,导致权限解析逻辑未生效
- 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
相关产品推荐
相关产品推荐

