许可代码和名称
问题描述:
在我的Spring Security项目的Spring Security表达我有@PreAuthorize
注释获得了以下方法:许可代码和名称
@PreAuthorize("hasAnyAuthority('PERMISSION_UPDATE_OWN_DECISION', 'PERMISSION_UPDATE_ANY_DECISION')")
@RequestMapping(value = "/{decisionId}/update", method = RequestMethod.POST)
public DecisionResponse updateDecision(@PathVariable @NotNull @DecimalMin("0") Long decisionId, @Valid @RequestBody UpdateDecisionRequest decisionRequest) {
....
}
我也使用Spring OAuth2和JWT令牌和所有机构存储此令牌内。现在,我使用相当长的权限名称,例如PERMISSION_UPDATE_OWN_DECISION
,并且希望替换它们以显着减少JWT令牌大小(权限部分)。
其中一个想法是引进许可的代码,类似:
1, PERMISSION_UPDATE_OWN_DECISION
2, PERMISSION_UPDATE_ANY_DECISION
其中1
是许可的代码和PERMISSION_UPDATE_OWN_DECISION
是一个权限名称。
但我不希望直接使用这些代码,因为它会降低我的代码的可读性,例如:
@PreAuthorize("hasAnyAuthority('1', '2')")
这个我想使用的东西,让我,而不是根据真实权限名称检索此代码,例如:
@PreAuthorize("hasAnyAuthority(getCode('PERMISSION_UPDATE_OWN_DECISION')), getCode('PERMISSION_UPDATE_ANY_DECISION'))")
如何通过Spring Security和Spring Security Expressions正确实现此目的?可能会有一些预先建立的方法来实现这一目标?
答
首先,您需要继承MethodSecurityExpressionRoot
的子类并使用您的逻辑创建自定义类。
public class CustomMethodSecurityExpressionRoot extends MethodSecurityExpressionRoot {
public boolean hasAnyAuthorityWithCodes(String... codes) {
String[] ids = // Your custom Logic to get Ids from Code
return hasAnyAuthority(ids);
}
}
然后子类DefaultMethodSecurityExpressionHandler
并重写它createEvaluationContext
方法。
@Override
public EvaluationContext createEvaluationContext(Authentication auth, MethodInvocation mi) {
MethodSecurityEvaluationContext ctx = new MethodSecurityEvaluationContext(auth, mi, parameterNameDiscoverer);
MethodSecurityExpressionRoot root = new CustomMethodSecurityExpressionRoot(auth);
root.setTrustResolver(trustResolver);
root.setPermissionEvaluator(permissionEvaluator);
root.setRoleHierarchy(roleHierarchy);
ctx.setRootObject(root);
return ctx;
}
最后你可以使你的配置中使用这个定制DefaultMethodSecurityExpressionHandler
的
<global-method-security>
<expression-handler ref="customMethodSecurityExpressionHandler"/>
</global-method-security>
并使用
@PreAuthorize("hasAnyAuthorityWithCodes('PERMISSION_UPDATE_OWN_DECISION','PERMISSION_UPDATE_ANY_DECISION')")
UPDATE
子类DefaultMethodSecurityExpressionHandler
,并覆盖createSecurityExpressionRoot
方法
protected MethodSecurityExpressionOperations createSecurityExpressionRoot(
Authentication authentication, MethodInvocation invocation) {
MethodSecurityExpressionRoot root = new CustomMethodSecurityExpressionRoot(
authentication);
root.setThis(invocation.getThis());
root.setTrustResolver(trustResolver);
root.setPermissionEvaluator(permissionEvaluator);
root.setRoleHierarchy(roleHierarchy);
root.setDefaultRolePrefix(defauleRolePrefix);
return root;
}
感谢您的回答。现在我有一个以下错误: 不能覆盖从AbstractSecurityExpressionHandler最终方法createEvaluationContext \t CustomMethodSecurityExpressionHandler.java这是Spring Security的核心4.0.3.RELEASE – alexanoid
谢谢通知看到更新 – shazin
现在getTrustResolver()和getDefaultRolePrefix()方法在我的CustomMethodSecurityExpressionHandler中都是未定义的 – alexanoid