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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 20:06:02