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

2022-08-31 10:41:56

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

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

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

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


答案 1

上述技术都不再有效。似乎Spring已经竭尽全力阻止用户覆盖SecurityExpressionRoot。

EDIT 11/19/14 设置弹簧以使用安全注释:

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

创建一个像这样:

@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表达式语言来访问当前的身份验证以及方法参数。@PreAuthorize

例如:

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

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

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

答案 2

您需要对两个类进行子类。

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

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

myMethodSecurityExpressionHandler将是其覆盖 的子类,在 上设置一个子类。DefaultMethodSecurityExpressionHandlercreateEvaluationContext()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;
}

推荐