一尘不染

如何创建用于Spring安全性表达语言注释的自定义方法

spring

我想创建一个类,该类添加用于Spring安全性表达语言的自定义方法,以通过注释进行基于方法的授权。

例如,我想创建一个自定义方法,例如“ customMethodReturningBoolean”,以这种方式使用:

  @PreAuthorize("customMethodReturningBoolean()")
  public void myMethodToSecure() { 
    // whatever
  }

我的问题是这个。如果可能,我应该子类化什么类来创建我的自定义方法,我将如何在spring xml配置文件中对其进行配置,然后有人给我提供以这种方式使用的自定义方法的示例?


阅读 495

收藏
2020-04-11

共2个答案

一尘不染

你需要子类化两个类。

首先,设置一个新的方法表达式处理程序

<global-method-security>
  <expression-handler ref="myMethodSecurityExpressionHandler"/>
</global-method-security>

myMethodSecurityExpressionHandler将是的一个子类DefaultMethodSecurityExpressionHandler,其覆盖createEvaluationContext(),设置的一个子类MethodSecurityExpressionRootMethodSecurityEvaluationContext

例如:

@Override
public EvaluationContext createEvaluationContext(Authentication auth, MethodInvocation mi) {
    MethodSecurityEvaluationContext ctx = new MethodSecurityEvaluationContext(auth, mi, parameterNameDiscoverer);
    MethodSecurityExpressionRoot root = new MyMethodSecurityExpressionRoot(auth);
    root.setTrustResolver(trustResolver);
    root.setPermissionEvaluator(permissionEvaluator);
    root.setRoleHierarchy(roleHierarchy);
    ctx.setRootObject(root);

    return ctx;
}
2020-04-11
一尘不染

所提到的技术都将不再起作用。看来Spring已经竭尽全力防止用户覆盖SecurityExpressionRoot。

编辑11/19/14设置Spring以使用安全注释:

<beans ... xmlns:sec="http://www.springframework.org/schema/security" ... >
...
<sec:global-method-security pre-post-annotations="enabled" />

创建一个像这样的bean:

@Component("mySecurityService")
public class MySecurityService {
    public boolean hasPermission(String key) {
        return true;
    }
}

然后在你的jsp中执行以下操作:

<sec:authorize access="@mySecurityService.hasPermission('special')">
    <input type="button" value="Special Button" />
</sec:authorize>

或注释方法:

@PreAuthorize("@mySecurityService.hasPermission('special')")
public void doSpecialStuff() { ... }

另外,你可以在批注中使用Spring Expression Language@PreAuthorize访问当前身份验证以及方法参数。

例如:

@Component("mySecurityService")
public class MySecurityService {
    public boolean hasPermission(Authentication authentication, String foo) { ... }
}

然后更新@PreAuthorize以匹配新的方法签名:

@PreAuthorize("@mySecurityService.hasPermission(authentication, #foo)")
public void doSpecialStuff(String foo) { ... }
2020-04-11