Spring Boot中基于Azure AD用户角色过滤Azure访问令牌失败问题
问题根源
Spring Security OAuth2 资源服务器默认只会提取JWT中的scp(scope)字段生成权限,不会主动读取Azure AD写入的roles字段。从你的调试日志也能看到,认证成功后Granted Authorities只有SCOPE_User.Read,没有加载你token里携带的Role-1、Role-2角色,所以角色校验失败。
解决方案
你需要自定义JWT权限转换器,指定从roles字段提取权限,有两种实现方式:
方式1:代码配置(通用性更强)
修改你的JWTSecurityConfig类,添加自定义转换器逻辑:
import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter; @Configuration public class JWTSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.cors().and() .authorizeRequests().antMatchers("**").hasAnyRole("Role-1") .and() .oauth2ResourceServer() .jwt() // 注册自定义的JWT转换器 .jwtAuthenticationConverter(jwtAuthenticationConverter()); } /** * 配置JWT权限转换器 */ private JwtAuthenticationConverter jwtAuthenticationConverter() { JwtAuthenticationConverter authenticationConverter = new JwtAuthenticationConverter(); JwtGrantedAuthoritiesConverter authoritiesConverter = new JwtGrantedAuthoritiesConverter(); // 指定从roles字段提取权限 authoritiesConverter.setAuthoritiesClaimName("roles"); // Spring的hasRole方法默认要求权限带ROLE_前缀,这里配置前缀 authoritiesConverter.setAuthorityPrefix("ROLE_"); authenticationConverter.setJwtGrantedAuthoritiesConverter(authoritiesConverter); return authenticationConverter; } }
如果不想使用ROLE_前缀,可以将setAuthorityPrefix参数设为空字符串,同时将校验规则从hasAnyRole("Role-1")改为hasAnyAuthority("Role-1")即可。
方式2:配置文件配置(适配Azure AD Starter)
你已经引入了Azure AD官方starter,也可以直接在application.yml中添加配置自动识别角色:
spring: cloud: azure: active-directory: claim-to-authority-prefix-map: # 指定roles字段的权限前缀为ROLE_ roles: ROLE_
额外优化建议
你引入的jjwt依赖是多余的,Spring Security OAuth2资源服务器已经自带JWT解析校验能力,可以直接移除该依赖避免冲突。
修改完成后重新启动服务,你会在调试日志中看到Granted Authorities已经包含ROLE_Role-1,角色校验即可正常通过。
内容的提问来源于stack exchange,提问作者Fredrik
相关产品推荐
相关产品推荐

