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

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (75)

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

例如,我想创建一个像'customMethodReturningBoolean'这样的自定义方法以便像这样使用:

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

如果可能的话,我应该创建自定义方法的子类是什么类,如何在Spring xml配置文件中配置它,然后有人给我一个以这​​种方式使用的自定义方法的示例?

提问于
用户回答回答于

你需要继承两个类。

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

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

例如:

@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;
}
用户回答回答于

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,并且你必须通过扩展类,重写方法,实现接口等来解决问题,那么你可能做错了什么。这是所有注释和XML,这就是为什么我们非常喜欢Spring而不是EJB(旧版本)。

此外,你可以在注释中使用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) { ... }

扫码关注云+社区

领取腾讯云代金券