如何使用基于Scope的@PreAuthorize来保护spring-security-oauth资源?

yan*_*kee 8 java spring spring-security-oauth2

我成功配置了spring-security-oauth2,以便外部应用程序可以使用我的应用程序进行身份验证.但是,基于外部应用程序并基于用户允许的内容,客户端只能访问我的API的一部分.可用子集由OAuth Scopes确定.

在经典的Spring应用程序中,我可以使用@PreAuthorize来强制基于角色的边界:

@Controller
public class MyController {
  @PreAuthorize("hasRole('admin')")
  @RequestMapping("...")
  public String doStuff() {
    // ...
  }
}
Run Code Online (Sandbox Code Playgroud)

使用OAuth和Scopes而不是角色时,我该怎么做?

yan*_*kee 18

Spring OAuth附带了OAuth2MethodSecurityExpressionHandler一个类,该类增加了使用@PreAuthorize表达式进行此类检查的功能.您需要做的就是注册这个类,例如,如果您使用的是Javaconfig:

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

现在你可以简单地使用:

@PreAuthorize("#oauth2.hasScope('requiredScope')")
Run Code Online (Sandbox Code Playgroud)

保护您的请求方法.要查看其他可用的方法,请hasScope查看该课程OAuth2SecurityExpressionMethods.

缺点是OAuth2MethodSecurityExpressionHandler扩展了DefaultMethodSecurityExpressionHandler,因此你不能将它与其他同样扩展这个类的类结合起来.

作为替代方案,您还可以将OAuth范围映射到经典用户角色.

  • 我正在使用Spring Boot 1.5.10,并且#oauth2.hasScope ...可以在不覆盖`createExpressionHandler()`的情况下工作。 (2认同)