2016-10-03 50 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