# oauth2 method-level security expressions

What should I do to use # oauth2 security expressions at the method level, for example, in the example below?

@RequestMapping(value = "email", method = RequestMethod.GET) @ResponseBody @PreAuthorize("#oauth2.hasScope('read')") public String email() { return " test@email.com "; } 

If I make a request for this resource, I get

  [INFO] java.lang.IllegalArgumentException: Failed to evaluate expression '#oauth2.hasScope('read')' [INFO] at org.springframework.security.access.expression.ExpressionUtils.evaluateAsBoolean(ExpressionUtils.java:14) [INFO] at org.springframework.security.access.expression.method.ExpressionBasedPreInvocationAdvice.before(ExpressionBasedPreInvocationAdvice.java:44) [INFO] at org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter.vote(PreInvocationAuthorizationAdviceVoter.java:57) [INFO] at org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter.vote(PreInvocationAuthorizationAdviceVoter.java:25) [INFO] at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:62) [INFO] at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:232) [INFO] at org.springframework.security.access.intercept.aspectj.AspectJMethodSecurityInterceptor.invoke(AspectJMethodSecurityInterceptor.java:43) [INFO] at org.springframework.security.access.intercept.aspectj.aspect.AnnotationSecurityAspect.ajc$around$org_springframework_security_access_intercept_aspectj_aspect_AnnotationSecurityAspect$1$c4d57a2b(AnnotationSecurityAspect.aj:63) [INFO] at pl.insert.controllers.ResourceController.email(ResourceController.java:22) 

The same works well if I specify access in my ResourceServerConfiguration instead of @Controllers methods

 @Configuration @EnableResourceServer public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http.requestMatchers().antMatchers("/oauth/resources/**"); http.authorizeRequests().anyRequest().access("#oauth2.hasScope('read')"); } } 

Standard security expressions such as @PreAuthorize ("allowAll") or @PreAuthorize ("denyAll") work as expected. So probably I need to somehow tell my AspectJMethodSecurityInterceptor to use the OAuth2WebSecurityExpressionHandler. Any ideas?

+8
source share
5 answers

To enable # oAuth2 security expressions, you only need to set the default expression handler as OAuth2MethodSecurityExpressionHandler instead of DefaultMethodSecurityExpressionHandler. Since OAuth2MethodSecurityExpressionHandler expands it anyway, then all the previous functionality remains the same. In my configuration, I use both GlobalMethodSecurityConfiguration and WebSecurityConfigurerAdapter.

 @Configuration @EnableGlobalMethodSecurity public class MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration { @Override protected MethodSecurityExpressionHandler createExpressionHandler() { return new OAuth2MethodSecurityExpressionHandler(); } } @Configuration @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter { ... } @Configuration @Import({ SecurityConfiguration.class, MethodSecurityConfiguration.class }) public class AppConfiguration { ... } 
+10
source

I think you also need to add: @EnableGlobalMethodSecurity ( prePostEnabled = true ) to make it work.

Responded to deferred page

+1
source

I had the same problem, but only in the unit test ( @WebMvcTest ). I had to add @EnableGlobalMethodSecurity to the inner class that defined the configuration for the test:

 @RunWith(SpringRunner.class) @WebMvcTest(MyController.class) public class MyControllerTest { @TestConfiguration @Import({JacksonCustomizations.class,SecuritySettings.class, OAuth2ServerConfiguration.class, WebSecurityConfiguration.class, TokenGrantersConfiguration.class}) @EnableGlobalMethodSecurity public static class TestConfig { } } 

UPDATE: In Spring Boot 2.x, you can get:

java.lang.IllegalStateException: as part of all the global settings of the method, support for annotations was not actually activated

The reason is that you added @EnableGlobalMethodSecurity actually including anything. To fix this, set at least one of the annotation properties to true. For instance:

 @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) 
0
source

A simpler solution would be to enable Spring Boot autoload. Adding the following dependency solved this for me:

 compile('org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.0.4.RELEASE') 
0
source

Thanks John, adding an autoconfiguration dependency solves the problem without declaring a bean or overriding a method. org.springframework.security.oauth.boot: spring-security oauth2-Autoconfiguration: version

0
source

All Articles