【问题标题】:Spring Security @PreAuthorize ByPass for specifc roleSpring Security @PreAuthorize 绕过特定角色
【发布时间】:2020-11-26 11:14:31
【问题描述】:

我正在使用 Spring 安全策略,需要全局角色 SUPER 的帮助,当令牌拥有它时,该角色必须绕过端点上的所有 @PreAuthorize。这是一个端点示例:

@GetMapping
@PreAuthorize("(hasAuthority('DOMAIN_FIND_ALL'))")
public ResponseEntity<ResponseDTO<List<DomainDTO>>> findAll() {
    return ResponseEntity.ok().body(domainService.findAll());
}

我为我的全球角色找到的工作方式是这样的

@GetMapping
@PreAuthorize("(hasAuthority('DOMAIN_FIND_ALL') or (hasAuthority('SUPER'))")
public ResponseEntity<ResponseDTO<List<DomainDTO>>> findAll() {
    return ResponseEntity.ok().body(domainService.findAll());
}

但是对于实现(hasAuthority('SUPER') 应用程序的每个端点来说太长了,所以我正在寻找一种以全局方式配置它的方法,这样,如果令牌具有该角色,则允许所有端点。

我尝试过的:

@Override
public void configure(HttpSecurity http) throws Exception {
   http.csrf().disable()
              .authorizeRequests()
              .otherStuffs..
              .antMatchers("/**").authenticated()
              .antMatchers("/**").hasRole("SUPER");
}

但它不起作用。有人对此有任何想法吗?

【问题讨论】:

    标签: java spring spring-security authorization


    【解决方案1】:

    更详细的解释请看下面的link(主要是第6节)。用作我回复基础的代码是:

    MySecurityExpressionRoot

    CustomMethodSecurityExpressionHandler

    以下代码适用于我:

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .otherStuffs..
                .antMatchers("/**").authenticated();  // hasRole("SUPER") isn't require
    }
    

    覆盖默认的MethodSecurityExpressionOperations接口:

    public class MySecurityExpressionRoot implements MethodSecurityExpressionOperations {
    
      // Same properties than provided
      // link for MySecurityExpressionRoot
      ...
    
      public MySecurityExpressionRoot(Authentication authentication) {
        if (authentication == null) {
            throw new IllegalArgumentException("Authentication object cannot be null");
        }
        this.authentication = authentication;
      }
    
      // This is the ONLY change, as you can see the "SUPER" was added as allowed
      @Override
      public final boolean hasAuthority(String authority) {
        return this.hasAnyAuthority(authority, "SUPER");
      }
    
      // Rest of the code is the same than provided
      // link for MySecurityExpressionRoot
      ...
    }
    

    现在我们需要将上面的类添加到 Spring 配置中:

    @Configuration  // Required although not include in "source CustomMethodSecurityExpressionHandler" class
    public class CustomMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler {
      private final AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
    
      @Override
      protected MethodSecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, MethodInvocation invocation) {
        final MySecurityExpressionRoot root = new MySecurityExpressionRoot(authentication);
        root.setPermissionEvaluator(getPermissionEvaluator());
        root.setTrustResolver(this.trustResolver);
        root.setRoleHierarchy(getRoleHierarchy());
        return root;
      }
    }
    

    现在您可以使用以下虚拟GET 端点对其进行验证:

    @GetMapping("/add-new-user")
    @PreAuthorize("hasAuthority('ADMIN')")
    public ResponseEntity<String> addNewUser() {
        return new ResponseEntity("[add-new-user] Testing purpose", OK);
    }
    

    任何具有ADMINSUPER 角色的用户都可以访问它。

    【讨论】:

      猜你喜欢
      • 2013-10-13
      • 2012-12-25
      • 1970-01-01
      • 2021-03-25
      • 1970-01-01
      • 2020-10-15
      • 2018-07-30
      • 2014-05-29
      • 2011-07-21
      相关资源
      最近更新 更多