2016-03-26 81 views
0

我需要爲我的REST API提供基於角色的訪問,並且我看到我們可以使用@PreAuthorize, @Secured來實現此目的。不過,我不確定我應該做什麼樣的改變,因爲目前我使用custom token based authentication mechanism爲會話生成令牌並自己處理它。如何整合基於角色的URL /方法訪問Spring Security安全

@RequestMapping(value = "login", method = RequestMethod.POST) 
     public @ResponseBody Result login(@RequestBody Credentials credentials) { 
     return loginService.login(credentials.getUsername(), credentials.getPassword()); 
     } 

Result類只包含爲每個請求傳遞的用戶生成的令牌。

現在,任何想法,我應該做出什麼樣的變化,如果我想限制API findById由用戶只能訪問,如果他是一部分,如果用戶是在特定角色

例如限制API的訪問ADMIN_ROLE然後我將不得不添加PreAuthorize註釋,但不知道這將如何確定用戶角色並自動阻止用戶。

@PreAuthorize("ADMIN_ROLE") 
@RequestMapping(value = "{id}", method = RequestMethod.GET) 
public @ResponseBody Group findById(@PathVariable int id) { 
    return groupParser.getGroupById(id, groupService.getGroupTree()); 
} 
+0

予處理基於自定義令牌認證 @RequestMapping(值= 「登錄」,方法= RequestMethod.POST) 公共結果@ResponseBody登錄(@RequestBody憑證的憑證){ 返回loginService.login(credentials.getUsername( ),credentials.getPassword()); } –

+0

請不要解釋配置,而是發佈它:-)如果你願意,你會得到更準確的答案。 –

+0

謝謝@StefanoCazzola。我做了一些更改並添加了更多信息。 –

回答

1

你需要做的是調整Spring Security配置。下面是一個XML配置的例子(我更習慣於它);不過,它在JavaConfig中也是可行的。

基本上,春季安全性由

<http ....> 
... 
</http> 

元素解僱。你需要像這樣寫(或者類似的東西)

<beans:bean id="authenticatedVoter" class="org.springframework.security.web.access.expression.WebExpressionVoter"> 
     <beans:property name="expressionHandler" ref="..." /> 
</beans:bean> 

<beans:bean id="roleVoter" 
     class="org.springframework.security.access.vote.RoleVoter"> 
     <beans:property name="rolePrefix" value="" /> <!-- if you want to customize role prefix --> 
</beans:bean> 

<beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased"> 
     <beans:constructor-arg> 
       <beans:list> 
         <beans:ref bean="roleVoter" /> 
         <beans:ref bean="authenticatedVoter" /> 
       </beans:list> 
     </beans:constructor-arg> 
</beans:bean> 

<!-- use-expressions enables the @PreAuthorize --> 
<http use-expressions="true" access-decision-manager-ref="accessDecisionManager"> 
.... 
</http> 

注意添加的bean:它們是三個Spring組件。

第一個包含未指定的參考。該公司預計實現的東西SecurityExpressionHandler:你的情況,你必須提供一個DefaultMethodSecurityExpressionHandler

然後,添加自定義標記的配置,你需要自己的過濾器和電線其寫入HTTP元素。您可以通過擴展Sp​​ring類,然後自定義其行爲

public class MyClientAuthenticationFilter extends OncePerRequestFilter { 
    .... 

    @Override 
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { 
     // custom logics here 
     // throw exception for not authenticated 
    } 
} 

做到這一點很容易,然後連線它

<bean class="x.y.z.MyClientAuthenticationFilter" id="myClientAuthenticationFilter" /> 
<http ....> 
    <custom-filter ref="myClientAuthenticationFilter" before="BASIC_AUTH_FILTER" /> 
</http> 

你應該基本做到了。

只記得在你的構建中包含spring-security-aspects:Spring security @PreAuthorize和其他註釋是通過AOP攔截的,因此你需要在你的類路徑中提供這些方面。

另外,請記住,這不是完整的配置:需要長篇文章才能將所有內容聯繫起來:這只是一個關於如何開始的例子。

欲瞭解更多信息,請參閱Spring Security文檔本身。

最後注意:如果您使用的是JvaConfig而不是XML,則應該有註釋可以消除部分thi配置,但是可以使用自定義過濾器。

希望它有幫助。

+0

感謝Stefano的提示。我基於你的xml配置準確地設置了java配置環境,並集成了我的應用程序的spring安全特性。我做的另一件事是我在我的應用程序中添加了一個過濾器,它在SecurityContextHolder.getContext中添加了一個認證,因爲我使用基於標記的身份驗證,並且在下一次調用時狀態會丟失,我需要重建狀態以便@PreAuthorize工作精細。 –