Java 是否向自定义权限计算器添加其他方法?

Java 是否向自定义权限计算器添加其他方法?,java,spring,spring-el,Java,Spring,Spring El,我有一个海关权限评估设置,如下所示 public class MyPermissionEvaluator implements PermissionEvaluator { @Override public boolean hasPermission(Authentication authentication, Object target, Object permission) { //do stuff } 那么在我的配置中 @Configuration

我有一个海关权限评估设置,如下所示

public class MyPermissionEvaluator implements PermissionEvaluator {

    @Override
    public boolean hasPermission(Authentication authentication, Object target, Object permission) {
        //do stuff
    }
那么在我的配置中

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends GlobalMethodSecurityConfiguration {

    @Autowired
    private MyPermissionEvaluator myPermissionEvaluator;

    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        DefaultMethodSecurityExpressionHandler methodSecurityExpressionHandler = new DefaultMethodSecurityExpressionHandler();
        methodSecurityExpressionHandler.setPermissionEvaluator(myPermissionEvaluator);
        return methodSecurityExpressionHandler;
    }
例如,在我的方法安全性的预授权上使用“hasPermission”时,这对于标准用例很有效

@PreAuthorize("hasPermission(#model.appName, 'RETRIVE')")
但是,我现在需要添加一个自定义方法来检查其他内容,而hasPermission对我来说是不够的,我需要有自己的自定义方法,所以我尝试将其添加到当前权限计算器中

public boolean myNewMethod(String app) {
        // do something
    }
然后在我的方法签名上,我更新了预授权

@PreAuthorize("hasPermission(#model.appName, 'RETRIVE') or myNewMethod(#model.value)")
这会导致以下错误“org.springframework.expression.spel.SpelEvaluationException:EL1004E:Method call:Method hasRoleAndStoreFor(java.lang.String)在org.springframework.security.access.expression.Method.MethodSecurityExpressionRoot类型上找不到”

然后我尝试将预授权更新为

@PreAuthorize("hasPermission(#model.appName, 'RETRIVE') or @myPermissionEvaluator.myNewMethod(#model.value)")
这给了我以下的错误

没有在上下文中注册bean解析器来解析对bean的myPermissionEvaluator的访问

然后,我尝试将该方法转移到一个新的服务中,并执行以下操作

@PreAuthorize("hasPermission(#model.appName, 'RETRIVE') or @newService.myNewMethod(#model.value)")
但是没有运气


有什么想法吗?我不知道如何使这项工作

如果您可以使该方法成为静态的,请使用


T(com.foo.MyClass).myNewMethod(#model.value)
如果可以将方法设置为静态,请使用


T(com.foo.MyClass).myNewMethod(#model.value)

这是另一种适合我的方法

  • 在开始计算所有安全表达式的位置实现根注释。在此类中添加自定义方法

     public class CustomMethodSecurityExpressionRoot extends SecurityExpressionRoot implements MethodSecurityExpressionOperations {
    
     private Authentication auth;
    
     public CustomMethodSecurityExpressionRoot( Authentication authentication) {
       super(authentication);
       this.auth=authentication;
    
     }
    
     // Your custom method
     public boolean myNewMethod(String app) {
      // do something
     }
    
     @Override
     public void setFilterObject(Object filterObject) {
       // TODO Auto-generated method stub
     }
    
     @Override
     public Object getFilterObject() {
      // TODO Auto-generated method stub
      return null;
     }
    
     @Override
     public void setReturnObject(Object returnObject) {
      // TODO Auto-generated method stub
     }
    
     @Override
     public Object getReturnObject() {
      // TODO Auto-generated method stub
      return null;
     }
    
     @Override
     public Object getThis() {
      // TODO Auto-generated method stub
      return null;
     }
    
    }
    
  • CustomMethodSecurityExpressionHandler类中插入CustomMethodSecurityExpressionRoot,该类扩展了DefaultMethodSecurityExpressionHandler

     public class CustomMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler {
    
     private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
    
     private ApplicationContext applicationContext;
    
    
     @Override
     public MethodSecurityExpressionOperations createSecurityExpressionRoot( Authentication authentication,
             MethodInvocation invocation) {
         CustomMethodSecurityExpressionRoot root = new CustomMethodSecurityExpressionRoot(authentication);
         root.setPermissionEvaluator(getPermissionEvaluator());
         root.setTrustResolver(this.trustResolver);
         root.setRoleHierarchy(getRoleHierarchy());
         return root;
     }
    
      @Override
      public void setApplicationContext(ApplicationContext applicationContext){
             super.setApplicationContext(applicationContext);
             this.applicationContext = applicationContext;
    
      }
    }
    
  • 接下来在方法安全配置中使用CustomMethodSecurityExpressionHandler

     @Configuration
     @EnableGlobalMethodSecurity(prePostEnabled = true)
     public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
    
     @Autowired
     ApplicationContext applicationContext;
    
     @Override
     protected MethodSecurityExpressionHandler createExpressionHandler() {
         CustomMethodSecurityExpressionHandler expressionHandler = 
           new CustomMethodSecurityExpressionHandler();
         expressionHandler.setApplicationContext(applicationContext);
         return expressionHandler;
     }
    
    }
    
  • 现在,您都已设置为在控制器中使用自定义方法

    @PreAuthorize("myNewMethod(#model.value)")
    
  • 此外,如果您需要任何服务在CustomMethodSecurityExpressionRoot类中自动连线,则必须使用setter来完成此操作

    private UserService userService;
    
    
    private PostService postService;
    
    public void setUserService(UserService userService){
      this.userService = userService;
    }
    public void setPostService(PostService postService) {
      this.postService = postService;
    }
    
    您需要在CustomMethodSecurityExpressionHandler类中调用此setters

    root.setUserService(applicationContext.getBean(UserService.class));
    root.setPostService(applicationContext.getBean(PostService.class));
    

    这是另一种对我有效的方法

  • 在开始计算所有安全表达式的位置实现根注释。在此类中添加自定义方法

     public class CustomMethodSecurityExpressionRoot extends SecurityExpressionRoot implements MethodSecurityExpressionOperations {
    
     private Authentication auth;
    
     public CustomMethodSecurityExpressionRoot( Authentication authentication) {
       super(authentication);
       this.auth=authentication;
    
     }
    
     // Your custom method
     public boolean myNewMethod(String app) {
      // do something
     }
    
     @Override
     public void setFilterObject(Object filterObject) {
       // TODO Auto-generated method stub
     }
    
     @Override
     public Object getFilterObject() {
      // TODO Auto-generated method stub
      return null;
     }
    
     @Override
     public void setReturnObject(Object returnObject) {
      // TODO Auto-generated method stub
     }
    
     @Override
     public Object getReturnObject() {
      // TODO Auto-generated method stub
      return null;
     }
    
     @Override
     public Object getThis() {
      // TODO Auto-generated method stub
      return null;
     }
    
    }
    
  • CustomMethodSecurityExpressionHandler类中插入CustomMethodSecurityExpressionRoot,该类扩展了DefaultMethodSecurityExpressionHandler

     public class CustomMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler {
    
     private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
    
     private ApplicationContext applicationContext;
    
    
     @Override
     public MethodSecurityExpressionOperations createSecurityExpressionRoot( Authentication authentication,
             MethodInvocation invocation) {
         CustomMethodSecurityExpressionRoot root = new CustomMethodSecurityExpressionRoot(authentication);
         root.setPermissionEvaluator(getPermissionEvaluator());
         root.setTrustResolver(this.trustResolver);
         root.setRoleHierarchy(getRoleHierarchy());
         return root;
     }
    
      @Override
      public void setApplicationContext(ApplicationContext applicationContext){
             super.setApplicationContext(applicationContext);
             this.applicationContext = applicationContext;
    
      }
    }
    
  • 接下来在方法安全配置中使用CustomMethodSecurityExpressionHandler

     @Configuration
     @EnableGlobalMethodSecurity(prePostEnabled = true)
     public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
    
     @Autowired
     ApplicationContext applicationContext;
    
     @Override
     protected MethodSecurityExpressionHandler createExpressionHandler() {
         CustomMethodSecurityExpressionHandler expressionHandler = 
           new CustomMethodSecurityExpressionHandler();
         expressionHandler.setApplicationContext(applicationContext);
         return expressionHandler;
     }
    
    }
    
  • 现在,您都已设置为在控制器中使用自定义方法

    @PreAuthorize("myNewMethod(#model.value)")
    
  • 此外,如果您需要任何服务在CustomMethodSecurityExpressionRoot类中自动连线,则必须使用setter来完成此操作

    private UserService userService;
    
    
    private PostService postService;
    
    public void setUserService(UserService userService){
      this.userService = userService;
    }
    public void setPostService(PostService postService) {
      this.postService = postService;
    }
    
    您需要在CustomMethodSecurityExpressionHandler类中调用此setters

    root.setUserService(applicationContext.getBean(UserService.class));
    root.setPostService(applicationContext.getBean(PostService.class));
    
    @预授权(“hasPermission(#model.appName,'retrieve')或T(com.foo.MyClass).myNewMethod(#model.value)”)??很好-请参阅@PreAuthorize(“hasPermission(#model.appName,'retrieve')或T(com.foo.MyClass).myNewMethod(#model.value)”??很好-请参阅