I've been racking my brain against this for some time. I have a client_credentials
JWT token from Azure with the following in the payload:
"roles": [ "read", "write" ]
I have a security configuration that looks similar to this:
@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()");
}
}
I am using:
org.springframework.boot:spring-boot-starter-oauth2-resource-server:2.1.0.RELEASE
We were using a private library which used @EnableResourceServer
, but have since stopped using it as it required internal support by creating custom code to connect to Azure - instead of using @EnableWebSecurity
which seems to works out of the box except for these special permissions.
So why won't the #oauth2
security expression methods work? I get the following exception:
java.lang.IllegalArgumentException: Failed to evaluate expression '#oauth2.clientHasRole("read")'
I've tried @EnableGlobalMethodSecurity(prePostEnabled = true)
and manually return an OAuth2MethodSecurityExpressionHandler()
by overriding GlobalMethodSecurityConfiguration.createExpressionHandler()
, but that did not work. See this this answer as reference.
As an alternate approach, I've also tried to look into adding some new GrantedAuthority
s but had no luck figuring out how to do that without manually authenticating a token myself. I saw that SecurityExpressionRoot
is used, but when checking hasRole()
, it relies on authorities to be set which is empty.
So I would love to have the #oauth.clientHasRole()
functionality work. Any help would be much appreciated!