Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to protect spring-security-oauth resources using @PreAuthorize based on Scope?

I successfully configured spring-security-oauth2 so that external apps can authenticate with my application. However based on the external app and based on what the user allows, only a subset of my API should be accessible to clients. The available subset is determined by the OAuth Scopes.

In classic Spring applications I could use @PreAuthorize to enforce boundaries based on roles:

@Controller
public class MyController {
  @PreAuthorize("hasRole('admin')")
  @RequestMapping("...")
  public String doStuff() {
    // ...
  }
}

How do I do the same when using OAuth and with Scopes instead of roles?

like image 413
yankee Avatar asked Nov 10 '15 20:11

yankee


People also ask

What's the difference between @secured and @PreAuthorize in Spring Security?

@Secured and @RolesAllowed are the same the only difference is @RolesAllowed is a standard annotation (i.e. not only spring security) whereas @Secured is spring security only. @PreAuthorize is different in a way that it is more powerful then the other 2. It allows for SpEL expression for a more fine-grained control.

How does @PreAuthorize work in spring boot?

Method-level security is implemented by placing the @PreAuthorize annotation on controller methods (actually one of a set of annotations available, but the most commonly used). This annotation contains a Spring Expression Language (SpEL) snippet that is assessed to determine if the request should be authenticated.

What is @PreAuthorize annotation in spring boot?

Spring Security provides method level security using @PreAuthorize and @PostAuthorize annotations. This is expression-based access control. The @PreAuthorize can check for authorization before entering into method. The @PreAuthorize authorizes on the basis of role or the argument which is passed to the method.

Does Spring Security support PKCE?

The latest version of Spring Security (5.2. 1 as of this writing) supports OAuth 2.0 and OpenID Connect natively. It supports PKCE for public clients.


1 Answers

Spring OAuth ships with the OAuth2MethodSecurityExpressionHandler, a class that adds the ability to do such checks using the @PreAuthorize expressions. All you need to do is register this class, e.g. like this if you are using Javaconfig:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public static class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        return new OAuth2MethodSecurityExpressionHandler();
    }
}

Now you can simply use:

@PreAuthorize("#oauth2.hasScope('requiredScope')")

to secure your request methods. To see which further methods are available besided hasScope check the class OAuth2SecurityExpressionMethods.

The downside is that OAuth2MethodSecurityExpressionHandler extends the DefaultMethodSecurityExpressionHandler and thus you cannot combine it with other classes that also extend this class.

As an alternative you could also map OAuth scopes to classic user roles.

like image 52
yankee Avatar answered Oct 04 '22 03:10

yankee