Spring Security OAuth2资源服务器JWT授权WebExpressionVoter拒绝访问问题
问题根因
- 权限字符串不匹配:你在安全配置中配置的访问规则是
.hasRole("test-role"),Spring Security会自动拼接ROLE_前缀,最终校验的权限为ROLE_test-role(使用中划线),但测试用例中给JWT授予的权限是ROLE_test_role(使用下划线),二者字符串完全不一致,直接导致鉴权被拒绝。 - 自定义JWT权限转换器未生效:你虽然定义了
JwtAuthenticationConverter和自定义RoleMapper的Bean,但Spring Security OAuth2资源服务器默认不会自动加载这个自定义转换器,需要手动绑定到资源服务器配置中,否则对接真实认证服务器时,你写的角色映射逻辑完全不会执行,也会出现权限解析错误。
修复方案
1. 统一权限命名规则
选择中划线或下划线其中一种命名格式,保证配置规则、测试用例、JWT返回的角色名三者完全一致:
例:统一使用下划线的话,修改安全配置的访问规则:
// 原代码:.antMatchers(HttpMethod.GET, "/message/**").hasRole("test-role") // 修改为: .antMatchers(HttpMethod.GET, "/message/**").hasRole("test_role")
或者统一使用中划线的话,修改测试用例的权限配置:
// 原代码:.with(jwt().authorities(new SimpleGrantedAuthority("ROLE_test_role"))) // 修改为: .with(jwt().authorities(new SimpleGrantedAuthority("ROLE_test-role")))
2. 绑定自定义JWT转换器到资源服务器配置
修改configure方法中资源服务器的配置,手动指定使用你自定义的转换器:
@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests(requests -> requests .antMatchers(HttpMethod.GET, "/message/**").hasRole("test_role") .anyRequest().authenticated() ) // 手动指定自定义的jwt转换器 .oauth2ResourceServer(resourceServer -> resourceServer .jwt(jwtConfigurer -> jwtConfigurer .jwtAuthenticationConverter(jwtAuthenticationConverter()) ) ); }
验证建议
可以在RoleMapper的convert方法中添加日志打印解析后的权限列表,确认生产环境下从JWT中解析的角色和预期一致,避免大小写、特殊符号差异导致的鉴权失败。
内容的提问来源于stack exchange,提问作者MPI
相关产品推荐
相关产品推荐

