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

Spring Security集成JWT时ADMIN角色权限不生效403问题求解

问题解决步骤

1. 调整路径匹配规则顺序

Spring Security的antMatcher规则按照声明顺序匹配,更宽泛的路径规则不能放在精细规则之前。你当前/user/**规则优先于/user/admin/**执行,所有/user/admin/*请求会先命中hasAnyRole("USER","ADMIN")校验,后续ADMIN专属规则直接失效,调整顺序即可:

// 先声明更精细的子路径规则
.antMatchers("/user/admin/**").hasRole("ADMIN")
// 再声明宽泛的父路径规则
.antMatchers("/user/**").hasAnyRole("USER", "ADMIN")

2. 处理角色前缀适配问题

Spring Security中hasRole()/hasAnyRole()方法默认会自动给角色名拼接ROLE_前缀,校验时会和权限列表中的值做匹配,两个适配方案二选一即可:

  • 方案一:权限存储/解析时统一添加前缀,比如你返回的权限列表里角色值为ROLE_ADMIN、ROLE_USER
  • 方案二:替换权限校验方法,把hasRole换成hasAuthority,同时对应修改配置和注解:
    // 配置类修改
    .antMatchers("/user/admin/**").hasAuthority("ADMIN")
    // 控制器注解修改
    @PreAuthorize("hasAuthority('ADMIN')")
    

如果要保留hasRole用法且不想加前缀,可以添加配置关闭默认前缀:

@Bean
public GrantedAuthorityDefaults grantedAuthorityDefaults() {
    return new GrantedAuthorityDefaults("");
}

3. 校验JWT授权过滤器逻辑

检查JWTAuthorizationFilter的解析逻辑:从JWT中取出角色后,是否正确封装为GrantedAuthority列表并注入到安全上下文,参考正确写法:

// 解析JWT获取角色列表后的封装逻辑
List<GrantedAuthority> authorities = Arrays.stream(roles)
        .map(SimpleGrantedAuthority::new)
        .collect(Collectors.toList());
UsernamePasswordAuthenticationToken authentication = 
        new UsernamePasswordAuthenticationToken(userAccount, null, authorities);
SecurityContextHolder.getContext().setAuthentication(authentication);

4. 规则优化建议

如果你已经开启@EnableGlobalMethodSecurity(prePostEnabled = true)使用方法级权限注解,可以直接删除HttpSecurity中/user相关的路径匹配规则,完全用接口上的@PreAuthorize注解控制权限,避免两层规则冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 08:15:03