@EnableWebSecurity 和 #oauth2.clientHasRole - 为什么它不起作用?



我一直在为此绞尽脑汁。我有一个来自 Azure 的client_credentialsJWT 令牌,有效负载中包含以下内容:

"roles": [ "read", "write" ]

我有一个类似于下面的安全配置:

@Configuration
@EnableWebSecurity
public SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**").authorizeRequests()
.antMatchers(HttpMethod.GET, "/api", "/api/**").access("#oauth2.clientHasRole("read")")
.antMatchers(HttpMethod.POST, "/api", "/api/**").access("#oauth2.clientHasRole("write")")
.anyRequest().access("#oauth2.isClient()");
}
}

我正在使用:

org.springframework.boot:spring-boot-starter-oauth2-resource-server:2.1.0.RELEASE

我们使用的是使用@EnableResourceServer的私人库,但此后停止使用它,因为它需要通过创建自定义代码连接到 Azure 的内部支持 - 而不是使用@EnableWebSecurity除了这些特殊权限之外,它似乎开箱即用。

那么,为什么#oauth2安全表达式方法不起作用呢?我得到以下异常:

java.lang.IllegalArgumentException: Failed to evaluate expression '#oauth2.clientHasRole("read")'

我已经尝试@EnableGlobalMethodSecurity(prePostEnabled = true)并通过覆盖GlobalMethodSecurityConfiguration.createExpressionHandler()手动返回OAuth2MethodSecurityExpressionHandler(),但这不起作用。请参阅此答案作为参考。

作为替代方法,我还尝试研究添加一些新的GrantedAuthority,但没有运气弄清楚如何在不自己手动验证令牌的情况下做到这一点。我看到使用了SecurityExpressionRoot,但是在检查hasRole()时,它依赖于要设置的权限,这是空的。

所以我希望#oauth.clientHasRole()功能正常工作。任何帮助将不胜感激!

我最终遵循了这个春季文档,并通过生成一个 bean 并引用它来制作自己的安全表达式。我不喜欢这个答案,并希望#oauth2表达式开箱即用。如果有人有首选答案,请发布。

最新更新