2016-10-03 68 views
2

在我的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令牌大小(权限部分)。

enter image description here

其中一个想法是引进许可的代码,类似:

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正确实现此目的?可能会有一些预先建立的方法来实现这一目标?

回答

1

首先,您需要继承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; 
    } 
+0

感谢您的回答。现在我有一个以下错误: 不能覆盖从AbstractSecurityExpressionHandler最终方法createEvaluationContext <的MethodInvocation> \t CustomMethodSecurityExpressionHandler.java这是Spring Security的核心4.0.3.RELEASE – alexanoid

+0

谢谢通知看到更新 – shazin

+0

现在getTrustResolver()和getDefaultRolePrefix()方法在我的CustomMethodSecurityExpressionHandler中都是未定义的 – alexanoid