【问题标题】:Spring security pass SecurityExpressionRoot to custom methodSpring security 将 SecurityExpressionRoot 传递给自定义方法
【发布时间】:2022-10-19 22:51:40
【问题描述】:

我想将SecurityExpressionRoot 类(我可以在@PreAuthorise() 注释内访问)传递给我的自定义checkAccess() 方法,该方法检查对特定方法的访问,使用一些基于权限、角色和我传递给它的附加变量的逻辑方法。 例如,在@PreAuthorise() 内部,我可以访问来自SecurityExpressionRoot 的方法。 hasAuthority()

有没有办法做到这一点?

控制器:

public class TestController {

    private final PreAuthorizeChecker preAuthorizeChecker;

    @Autowired
    public TestController(PreAuthorizeChecker preAuthorizeChecker) {
        this.preAuthorizeChecker = preAuthorizeChecker;
    }

    @GetMapping(path = "/test")
    @PreAuthorize("@preAuthorizeChecker.checkAccess(/*SecurityExpressionRoot.getSomehow()*/)")    //How to obtain SecurityExpressionRoot instance?
    public ResponseEntity<Void> get() {
        return;
    }

PreAuthorizeChecker:

@Component
public class PreAuthorizeChecker {

    @Autowired
    public PreAuthorizeChecker() {
    }

    public boolean checkAccess(SecurityExpressionRoot securityExpressionRoot) {
        //do sth with securityExpressionRoot
        return true;
    }
}

【问题讨论】:

    标签: java spring spring-security


    【解决方案1】:

    您可能会发现 Baelding.com 上此博客的第 5 部分 A Custom Security Expression with Spring Security 很有帮助。作者建议扩展 SecurityExpressionRoot 并将您的自定义方法添加到新类中,如下所示:

    public class CustomMethodSecurityExpressionRoot extends SecurityExpressionRoot implements MethodSecurityExpressionOperations {
    
           public CustomMethodSecurityExpressionRoot(Authentication authentication) {
                super(authentication);
           }
    
           public boolean checkAccess() {
                //do sth with securityExpressionRoot
                return true;
           }
    
    ...
    }
    

    然后,您需要将该新类注入到表达式处理程序中,如下所示:

    public class CustomMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler {
    
          private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
    
          @Override
          protected MethodSecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, MethodInvocation invocation) {
               CustomMethodSecurityExpressionRoot root = new CustomMethodSecurityExpressionRoot(authentication);
               root.setPermissionEvaluator(getPermissionEvaluator());
               root.setTrustResolver(this.trustResolver);
               root.setRoleHierarchy(getRoleHierarchy());
               return root;
          }
    }
    

    最后,您只需要在安全配置中创建表达式处理程序,如下所示:

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

    然后你的新表达式应该可用:

      @PreAuthorize("checkAccess()")
      public ResponseEntity<Void> get() {
          return;
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-29
      • 2020-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-10
      • 1970-01-01
      相关资源
      最近更新 更多