我想创建一个类,该类添加用于Spring安全性表达语言的自定义方法,以通过注释进行基于方法的授权。
例如,我想创建一个自定义方法,例如“ customMethodReturningBoolean”,以这种方式使用:
@PreAuthorize("customMethodReturningBoolean()") public void myMethodToSecure() { // whatever }
我的问题是这个。如果可能,我应该子类化什么类来创建我的自定义方法,我将如何在spring xml配置文件中对其进行配置,然后有人给我提供以这种方式使用的自定义方法的示例?
你需要子类化两个类。
首先,设置一个新的方法表达式处理程序
<global-method-security> <expression-handler ref="myMethodSecurityExpressionHandler"/> </global-method-security>
myMethodSecurityExpressionHandler将是的一个子类DefaultMethodSecurityExpressionHandler,其覆盖createEvaluationContext(),设置的一个子类MethodSecurityExpressionRoot的MethodSecurityEvaluationContext。
myMethodSecurityExpressionHandler
DefaultMethodSecurityExpressionHandler
createEvaluationContext()
MethodSecurityExpressionRoot
MethodSecurityEvaluationContext
例如:
@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已经竭尽全力防止用户覆盖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访问当前身份验证以及方法参数。
@PreAuthorize
@Component("mySecurityService") public class MySecurityService { public boolean hasPermission(Authentication authentication, String foo) { ... } }
然后更新@PreAuthorize以匹配新的方法签名:
@PreAuthorize("@mySecurityService.hasPermission(authentication, #foo)") public void doSpecialStuff(String foo) { ... }