《Spring Security3》第二章第三部分翻譯(中)

請求是怎樣被受權的?

Spring Security的默認過濾器鏈中,最後一個servelt過濾器是FilterSecurityInterceptor,它的做用是判斷一個特定的請求是被容許仍是被拒絕。在FilterSecurityInterceptor被觸發的時候,安全實體已經通過了認證,因此係統知道他們是合法的用戶。(其實也有多是匿名的用戶,譯者注)。請記住的一點是,Authentication提供了一個方法((List<GrantedAuthority> web

getAuthorities()),將會返回當前安全實體的一系列權限列表。受權的過程將使用這個方法提供的信息來決定一個特定的請求是否會被容許。spring

須要記住的是受權是一個二進制的決策——一個用戶要麼有要麼沒有訪問一個受保護資源的權限。在受權中,沒有模棱兩可的情景。安全

Spring Security中,良好的面向對象設計隨處可見,在受權決策管理中也不例外。回憶一下咱們在本章前面的討論,一個名爲訪問控制決策器(access decision manager)的組件負責做出受權決策。ide

Spring Security中,o.s.s.access.AccessDecisionManager接口定義了兩個簡單而合理的方法,它們可以用於請求的決策判斷流程:url

<!--[if !supportLists]-->l <!--[endif]-->supports:這個邏輯操做實際上包含兩個方法,它們容許AccessDecisionManager的實現類判斷是否支持當前的請求。spa

<!--[if !supportLists]-->l <!--[endif]-->decide:基於請求的上下文和安全配置,容許AccessDecisionManager去核實訪問是否被容許以及請求是否可以被接受。decide方法實際上沒有返回值,經過拋出異常來代表對請求訪問的拒絕。設計

AuthenticationException及其子類在認證過程當中的使用很相似,特定類型的異常可以代表應用在受權決策中的不一樣處理結果。o.s.s.access.AccessDeniedException是在受權領域裏最多見的異常,所以值得過濾器鏈進行特殊的處理。咱們將在第六章中詳細介紹它的高級配置。xml

AccessDecisionManager是可以經過標準的Spring bean綁定和引用實現徹底的自定義配置。AccessDecisionManager的默認實現提供了一個基於AccessDecisionVoter接口和投票集合的受權機制。對象

投票器(voter)是在受權過程當中的一個重要角色,它的做用是評估如下的內容:接口

<!--[if !supportLists]-->l <!--[endif]-->要訪問受保護資源的請求所對應上下文(如URL請求的IP地址);

<!--[if !supportLists]-->l <!--[endif]-->用戶的憑證信息(若是存在的話);

<!--[if !supportLists]-->l <!--[endif]-->要試圖訪問的受保護資源;

<!--[if !supportLists]-->l <!--[endif]-->系統的配置以及要訪問資源自己的配置參數。

AccessDecisionManager還會負責傳遞要請求資源的訪問聲明信息(在代碼中爲ConfigAttribute接口的實現類)給投票器。在web URL的請求中,投票器將會獲得資源的訪問聲明信息。若是看一下咱們配置文件中很是基礎的攔截聲明,咱們可以看到ROLE_USER被設置爲訪問配置並用於用戶試圖訪問的資源:

<intercept-url pattern="/*" access="ROLE_USER"/>

投票器將會對用戶是否可以訪問指定的資源作出一個判斷。Spring Security容許過濾器在三種決策結果中作出一種選擇,它們的邏輯定義在o.s.s.access.AccessDecisionVoter接口中經過常量進行了定義。

決策類型

描述

Grant (ACCESS_GRANTED)

投票器容許對資源的訪問

Deny (ACCESS_DENIED)

投票器拒絕對資源的訪問

Abstain (ACCESS_ABSTAIN)

投票器對是否可以訪問作了棄權處理(即沒有作出決定)。可能在多種緣由下發生,如:

<!--[if !supportLists]-->l <!--[endif]-->投票器沒有確鑿的判斷信息;

<!--[if !supportLists]-->l <!--[endif]-->投票器不能對這種類型的請求作出決策。

正如你從訪問決策相關類和接口的設計中能夠猜到的那樣,Spring Security的這部分被精心設計,因此認證和訪問控制的使用場景並不只僅限於web領域。咱們將會在:精確的訪問控制中關於方法級別的安全時,再次講解投票器和訪問控制管理。

當將他們組合在一塊兒,「對web請求的默認認證檢查」的總體流程將以下圖所示:



咱們能夠看到ConfigAttribute可以從配置聲明(在DefaultFilterInvocationSecurityMetadataSource類中保存)中傳遞數據到投票器,投票器並不須要其餘的類來理解ConfigAttribute的內容。這種分離可以爲新類型的安全聲明(例如咱們將要看到的方法安全聲明)使用相同的訪問決策模式提供基礎。

配置access decision集合

實際上Spring Security容許經過security命名空間來配置AccessDecisionManager<http>元素的access-decision-manager-ref屬性來指明一個實現了AccessDecisionManagerSpring BeanSpring Security提供了這個接口的三個實現類,都在o.s.s.access.vote包中:

類名

描述

AffirmativeBased

若是有任何一個投票器容許訪問,請求將被馬上容許,而無論以前可能有的拒絕決定。

ConsensusBased

多數票(容許或拒絕)決定了AccessDecisionManager的結果。平局的投票和空票(全是棄權的)的結果是可配置的。

UnanimousBased

全部的投票器必須全是容許的,不然訪問將被拒絕。

配置使用UnanimousBased的訪問決策管理器(access decision manager

若是你想修改咱們的應用來使用UnanimousBased訪問決策管理器,咱們須要修改兩個地方。首先讓咱們在<http>元素上添加access-decision-manager-ref屬性:

<http auto-config="true"

access-decision-manager-ref="unanimousBased" >

這是一個標準的Spring Bean的引用,因此這須要對應一個beanid屬性。接下來,咱們要定義這個bean(在dogstore-base.xml中),並與咱們引用的有相同的id

<bean class="org.springframework.security.access.vote.UnanimousBased"

id="unanimousBased">

<property name="decisionVoters">

<list>

<ref bean="roleVoter"/>

<ref bean="authenticatedVoter"/>

</list>

</property>

</bean>

<bean class="org.springframework.security.access.vote.RoleVoter"

id="roleVoter"/>

<bean class="org.springframework.security.access.vote.

AuthenticatedVoter" id="authenticatedVoter"/>

你可能象知道decisionVoters屬性是什麼。這個屬性在咱們不聲明AccessDecisionManager時,是自動配置的。默認的AccessDecisionManager要求咱們配置投票器的一個列表,它們將會在認證決策時用到。這裏列出的兩個投票器是security命名空間配置默認提供的。

遺憾的是,Spring Security沒有爲咱們提供太多的投票器,可是實現AccessDecisionVoter接口並在配置中添加咱們的實現並非一件困難的事情。咱們將在第六章看一個例子。

咱們引用的兩個投票器介紹以下:

類名

描述

例子

o.s.s.access.

vote.RoleVoter

檢查用戶是否擁有聲明角色的權限(GrantedAuthority)。access屬性定義了GrantedAuthority的一個列表。預期會有ROLE_前綴,但這也是可配置的。

access="ROLE_USER,ROLE_ADMIN"

o.s.s.access.

vote.AuthenticatedVoter

支持特定類型的聲明,容許使用通配符:

<!--[if !supportLists]-->l <!--[endif]-->IS_AUTHENTICATED_FULLY——容許提供完整的用戶名和密碼的用戶訪問;

<!--[if !supportLists]-->l <!--[endif]-->IS_AUTHENTICATED_REMEMBERED——若是用戶是經過remember me功能認證的則容許訪問;

<!--[if !supportLists]-->l <!--[endif]-->IS_AUTHENTICATED_ANONYMOUSLY——容許匿名用戶訪問。

access=" IS_AUTHENTICATED_ANONYMOUSLY

相關文章
相關標籤/搜索