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
相关产品推荐
相关产品推荐

