【问题标题】:Call a private method in Spring @PreAuthorize在 Spring @PreAuthorize 中调用私有方法
【发布时间】:2013-08-30 11:57:31
【问题描述】:

我正在使用 Spring Security 对方法进行权限检查。我想调用一个私有方法来收集一些数据发送到hasPermission() 方法。以下是我尝试执行的操作,我得到 SpelEvaluationException,因为 Spring 正在寻找 MethodSecurityExpressionRoot 中的 localPrivateMethod。有没有办法做到这一点?谢谢。

@PreAuthorize("hasPermission(new Object[]{#arg3, #localPrivateMethod(#arg1,#arg2)}, 'canDoThis')")  
public long publicMethod1(long arg1, long arg2, long arg3) {}

private String localPrivateMethod(long a1, long a2) {}

【问题讨论】:

标签: spring spring-mvc spring-security


【解决方案1】:

您将无法调用私有方法,但可以调用另一个 Spring bean 中的方法。在我的应用程序中,我有一个名为 permissionEvaluator 的 @Component。然后我像这样在@PreAuthorize 中引用它:

@PreAuthorize("@permissionEvaluator.canViewImageSet( #imageSet, principal )")
@RequestMapping(value="/image", method=RequestMethod.GET )
public String getImage(
        @RequestParam(value="imageSet", required=false) ImageSet imageSet ) {
    // method body
}

PermissionEvaluatorImpl 看起来像这样:

@Component(value="permissionEvaluator")
public class PermissionEvaluatorImpl implements PermissionEvaluator
{
    public PermissionEvaluatorImpl() {}

    /**
     * Determine if a user can view a given image.
     */
    public boolean canViewImageSet( ImageSet imageSet, UserDetailsAdapter user )
    {
        // code to see if they should view this image
    }
}

PermissionEvaluator 是我自己的接口,没有什么特别之处,只是我需要评估的任何方法。

【讨论】:

  • 我花了整整一个小时调查类似的问题,当我看到你的答案时,我记得 spring 为其他类的代理应用拦截器,当调用同一类中的方法时,代理无法应用 stackoverflow.com/questions/13564627/…
  • 您还需要做什么吗?我试过了,但它不起作用。
  • 如果您的 permissionEvaluator 是一个 bean,那么您应该没问题。如果您手动设置 bean 而不是使用组件扫描,那么您必须确保 permissionEvaluator bean 存在。
  • PermissionEvaluator 是一个现有的 Spring Security 接口,至少它在 spring security core 5.1.5 中所以这段代码不会工作,因为你没有实现 PermissionEvaluator 的方法。如果您不打算使用 PermissionEvaluator,我建议您重命名您的自定义界面。
  • 我注意到我们需要限定 bean 以便 @PreAuthorize。有谁知道为什么?
【解决方案2】:

不能调用私有方法,但是可以通过this.引用“这个组件”:

@PreAuthorize("hasPermission(new Object[]{#arg3, /* HERE: */ this.localPublicMethod(#arg1,#arg2)}, 'canDoThis')")   
public long publicMethod1(long arg1, long arg2, long arg3)
{
}

public String localPublicMethod(long a1, long a2)
{
}

【讨论】:

  • 出现以下错误 EL1011E:方法调用:尝试在空上下文对象上调用方法 validate(java.lang.String)
【解决方案3】:

可以使用 @someController.localPublicMethod(#arg1,#arg2)

以简单的方式完成

无需实现permissionEvaluator

@RestController
public class SomeController{

@PreAuthorize("hasPermission(new Object[]{#arg3, @someController.localPublicMethod(#arg1,#arg2)}, 'canDoThis')")  
public long publicMethod1(long arg1, long arg2, long arg3) {}

public String localPublicMethod(long a1, long a2) {}

}
}

localPublicMethod 不能是私有的

对于权限评估者 - 有更好的方法可以参考下面的链接 https://www.baeldung.com/spring-security-create-new-custom-security-expression

【讨论】:

    猜你喜欢
    • 2014-08-03
    • 1970-01-01
    • 2014-09-13
    • 2017-07-29
    • 2011-10-15
    • 1970-01-01
    • 1970-01-01
    • 2018-05-03
    • 1970-01-01
    相关资源
    最近更新 更多