acegi技術概覽3

 認證

    正如我們在手冊開始部分所說的那樣,Acegi Security適用於很多認證環境。雖然我們建議大家使用Acegi Security自身的認證功能而不是和容器管理認證(Container Managed Authentication)集成,但是我們仍然支持這種和你私有的認證系統集成的認證。讓我們先從Acegi Security完全自行管理管理web安全的角度來探究一下認證,這也是最複雜和最通用的情形。

    想象一個典型的web應用的認證過程:

1.你訪問首頁,點擊一個鏈接。

2.一個請求被髮送到服務器,服務器判斷你是否請求一個被保護的資源。

3.因爲你當前未被認證,服務器發回一個迴應,表明你必須通過認證。這個迴應可能是一個HTTP迴應代碼,或者重定向到一個特定的網頁。

4.基於不同的認證機制,你的瀏覽器會重定向到一個網頁好讓你填寫表單,或者瀏覽器會用某種方式獲取你的身份認證(例如一個BASIC認證對話框,一個cookie,一個X509證書等等。)。

5.瀏覽器會發回給服務器一個迴應。可能是一個包含了你填寫的表單內容的HTTP POST,或者一個包含你認證詳細信息的HTTP header。

6.接下來服務器會判斷提供的認證信息是否有效。如果它們有效,你進入到下一步。如果它們無效,那麼通常請求你的瀏覽器重試一次(你會回到上兩步)。

7.你引發認證的那個請求會被重試。但願你認證後有足夠的權限訪問那些被保護的資源。如果你有足夠的訪問權限,請求就會成功。否則,你將會受到一個意味"禁止"的HTTP403錯誤代碼。

    在Acegi Security中,對應上述的步驟,有對應的類。主要的參與者(按照被使用的順序)是:ExceptionTranslationFilter, AuthenticationEntryPoint, 認證機制(authentication mechanism), 以及AuthenticationProvider。

    ExceptionTranslationFilter是Acegi Security用來檢測任何拋出的安全異常的過濾器(filter)。這種異常通常是由AbstractSecurityInterceptor拋出的,它是授權服務的主要提供者。我們將會在下一部分討論AbstractSecurityInterceptor,現在我們只需要知道它產生Java異常,並且對於HTTP或者如何認證一個principal一無所知。反而是ExceptionTranslationFilter提供這樣的服務,它負責要麼返回403錯誤代碼(如果principal通過了認證,只是缺少足夠的權限,象上述第7步那樣),要麼加載一個AuthenticationEntryPoint (如果principal還沒有被認證,那麼我們要從第3步開始)。

    AuthenticationEntryPoint負責上述的第3步。如你所想,每個web應用都有一個默認的認證策略(象Acegi Security中幾乎所有的東西一樣,它也是可配置的,不過我們現在還是還是從簡單開始)。每個主流的認證系統都有它自己的AuthenticationEntryPoint實現,負責執行第3步中描述的動作。

    當瀏覽器確定要發送你的認證信息(HTTP 表單或者HTTP header),服務器上需要有什麼東西來"收集"這些認證信息。現在我們在上述的第6步。在Acegi Security中對從用戶代理(通常是瀏覽器)收集認證信息有一個特定的名字,這個名字是"認證機制(authentication mechanism)"。當認證信息從客戶代理收集過來以後,一個"認證請求(Authenticationrequest)"對象被創建,併發送到AuthenticationProvider。

    Acegi Security中認證的最後一環是一個AuthenticationProvider。非常簡單,它的職責是取用一個認證請求(Authentication request)對象,並且判斷它是否有效。這個provider要麼拋出一個異常,要麼返回一個組裝完畢的Authentication對象。還記得我們的好朋友UserDetails 和 UserDetailsService吧?如果沒有,回到前一部分重新回憶一下。大部分的AuthenticationProviders都會要求UserDetailsService提供一個UserDetails對象。如前所述,大部分的應用程序會提供自己的UserDetailsService,儘管有些會使用Acegi Security提供的JDBC或者 in-memory實現。作爲成品的UserDetails 對象,特別是其中的GrantedAuthority[]s,在構建完備的Authentication對象時會被使用。

    當認證機制(authentication mechanism)取回組裝完全的Authentication對象後,它將會相信請求是有效的,將Authentication放到SecurityContextHolder中,並且將原始請求取回(上述第7步)。反之,AuthenticationProvider則拒絕請求,認證機制(authentication mechanism)會請求用戶重試(上述第2步)。

    在講述典型的認證流程的同時,有個好消息是Acegi Security不關心你是如何把Authentication放到SecurityContextHolder內的。唯一關鍵的是在AbstractSecurityInterceptor授權一個請求之前,在SecurityContextHolder中包含一個代表了principal的Authentication。

    你可以(很多用戶確實)實現自己的過濾器(filter)或者MVC控制器(controller)來提供和不是基於Acegi Security的認證系統交互。例如,你可能使用使用容器管理認證(Container Managed Authentication),從ThreadLocal或者JNDI中獲取當前用戶信息,使得它有效。或者,你工作的公司有一個遺留的私有認證系統,而它是公司"標準",你對它無能爲力。在這種情況之下也是非常容易讓Acegi Security運作起來,提供認證能力。你所需要做的是寫一個過濾器(或等價物)從某處讀取第三方用戶信息,構建一個Acegi Security式的Authentication對象,把它放到SecurityContextHolder中。這非常容易做,也是一種廣泛支持的集成方式。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章