<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    狼愛上貍

    我胡漢三又回來(lái)了

    acegi,IBM的Acegi Security System(2)

    2007 年 6 月 21 日

    了解了 Acegi 安全系統(tǒng)(Acegi Security System)的 基礎(chǔ)知識(shí) 后,我們將介紹該系統(tǒng)的更加高級(jí)的應(yīng)用。在本文中,Bilal Siddiqui 向您展示了如何結(jié)合使用 Acegi 和一個(gè) LDAP 目錄服務(wù)器,實(shí)現(xiàn)靈活的具有高性能的 Java™ 應(yīng)用程序的安全性。還將了解如何編寫訪問控制策略并將其存儲(chǔ)在 ApacheDS 中,然后配置 Acegi 使其與目錄服務(wù)器交互,從而實(shí)現(xiàn)身份驗(yàn)證和授權(quán)的目的。

    這期共分三部分的系列文章介紹了如何使用 Acegi 安全系統(tǒng)保護(hù) Java 企業(yè)應(yīng)用程序。在 本系列第一篇文章 中,我介紹了 Acegi 并解釋了如何使用安全過濾器實(shí)現(xiàn)一個(gè)簡(jiǎn)單的基于 URL 的安全系統(tǒng)。在第二篇文章中,我將討論 Acegi 的更加高級(jí)的應(yīng)用,首先我將編寫一個(gè)訪問控制策略并將其存儲(chǔ)在 ApacheDS 中,ApacheDS 是一個(gè)開源的 LDAP 目錄服務(wù)器。我還將展示配置 Acegi 的方法,使它能夠與目錄服務(wù)器交互并實(shí)現(xiàn)您的訪問控制策略。本文的結(jié)尾提供了一個(gè)示例應(yīng)用程序,它使用 ApacheDS 和 Acegi 實(shí)現(xiàn)了一個(gè)安全的訪問控制策略。

    實(shí)現(xiàn)訪問控制策略通常包含兩個(gè)步驟:

    1. 將有關(guān)用戶和用戶角色的數(shù)據(jù)存儲(chǔ)在目錄服務(wù)器中。
    2. 編寫安全代碼,它將定義有權(quán)訪問并使用數(shù)據(jù)的人員。

    Acegi 將減輕代碼編寫的工作,因此在這篇文章中,我將展示如何將用戶和用戶角色信息存儲(chǔ)到 ApacheDS 中,然后實(shí)現(xiàn)這些信息的訪問控制策略。在該系列的最后一篇文章中,我將展示如何配置 Acegi,實(shí)現(xiàn)對(duì) Java 類的安全訪問。

    您可以在本文的任何位置 下載樣例應(yīng)用程序。參見 參考資料 下載 Acegi、Tomcat 和 ApacheDS,您需要使用它們運(yùn)行樣例代碼和示例應(yīng)用程序。

    LDAP 基礎(chǔ)知識(shí)

    輕量級(jí)目錄訪問協(xié)議(Lightweight Directory Access Protocol,LDAP)可能是最流行的一種定義數(shù)據(jù)格式的協(xié)議,它針對(duì)常見的目錄操作,例如對(duì)存儲(chǔ)在目錄服務(wù)器中的信息執(zhí)行的讀取、編輯、搜索和刪除操作。本節(jié)將簡(jiǎn)要解釋為什么目錄服務(wù)器是屬性文件存儲(chǔ)安全信息的首選,并展示如何在 LDAP 目錄中組織和托管用戶信息。

    為什么要使用目錄服務(wù)器?

    本系列第一部分向您介紹了一種簡(jiǎn)單的方法,可以將用戶信息以屬性文件的形式保存起來(lái)(參見 第 1 部分,清單 6)。屬性文件以文本格式保存用戶名、密碼和用戶角色。對(duì)于大多數(shù)真實(shí)應(yīng)用程序而言,使用屬性文件存儲(chǔ)安全信息遠(yuǎn)遠(yuǎn)不夠。各種各樣的理由表明,目錄服務(wù)器通常都是更好的選擇。其中一個(gè)原因是,真實(shí)的企業(yè)應(yīng)用程序可以被大量用戶訪問 —— 通常是幾千名用戶,如果應(yīng)用程序?qū)⑵洳糠止δ芄_給用戶和供應(yīng)商時(shí)更是如此。頻繁搜索文本文件中隨意存儲(chǔ)的信息,這樣做的效率并不高,但是目錄服務(wù)器對(duì)這類搜索進(jìn)行了優(yōu)化。

    第 1 部分的清單 6 中的屬性文件演示了另一個(gè)原因,該文件組合了用戶和角色。在真實(shí)的訪問控制應(yīng)用程序中,您通常都需要分別定義和維護(hù)用戶和角色信息,這樣做可以簡(jiǎn)化用戶庫(kù)的維護(hù)。目錄服務(wù)器為更改或更新用戶信息提供了極大的靈活性,例如,反映職位升遷或新聘用人員。參見 參考資料 以了解更多關(guān)于目錄服務(wù)器的使用及其優(yōu)點(diǎn)的信息。

    LDAP 目錄設(shè)置

    如果希望將用戶信息存儲(chǔ)在一個(gè) LDAP 目錄中,您需要理解一些有關(guān)目錄設(shè)置的內(nèi)容。本文并沒有提供對(duì) LDAP 的完整介紹(參見 參考資料),而是介紹了一些在嘗試結(jié)合使用 Acegi 和 LDAP 目錄之前需要了解的基本概念。

    LDAP 目錄以節(jié)點(diǎn)樹的形式存儲(chǔ)信息,如圖 1 所示:


    圖 1. LDAP 目錄的樹狀結(jié)構(gòu)
    圖 1. LDAP 目錄的樹狀結(jié)構(gòu)

    在圖 1 中,根節(jié)點(diǎn)的名稱為 org。根節(jié)點(diǎn)可以封裝與不同企業(yè)有關(guān)的數(shù)據(jù)。例如,本系列第 1 部分開發(fā)的制造業(yè)企業(yè)被顯示為 org 節(jié)點(diǎn)的直接子節(jié)點(diǎn)。該制造業(yè)企業(yè)具有兩個(gè)名為 departmentspartners 的子節(jié)點(diǎn)。

    partners 子節(jié)點(diǎn)封裝了不同類型的合作伙伴。圖 1 所示的三個(gè)分別為 customersemployeessuppliers。注意,這三種類型的合作伙伴其行為與企業(yè)系統(tǒng)用戶一樣。每一種類型的用戶所扮演的業(yè)務(wù)角色不同,因此訪問系統(tǒng)的權(quán)利也不同。

    類似地,departments 節(jié)點(diǎn)包含該制造業(yè)企業(yè)的不同部門的數(shù)據(jù) —— 例如 engineeringmarketing 字節(jié)點(diǎn)。每個(gè)部門節(jié)點(diǎn)還包含一組或多組用戶。在 圖 1 中,engineers 組是 engineering 部門的子節(jié)點(diǎn)。

    假設(shè)每個(gè)部門的子節(jié)點(diǎn)表示一組用戶。因此,部門節(jié)點(diǎn)的子節(jié)點(diǎn)具有不同的用戶成員。例如,設(shè)計(jì)部門的所有工程師都是 engineering 部門內(nèi) engineers 組的成員。

    最后,注意 圖 1departments 節(jié)點(diǎn)的最后一個(gè)子節(jié)點(diǎn)。specialUser 是一名用戶,而非一組用戶。在目錄設(shè)置中,像 alicebob 之類的用戶一般都包含在 partners 節(jié)點(diǎn)中。我將這個(gè)特殊用戶包含在 departments 節(jié)點(diǎn)中,以此證明 Acegi 允許用戶位于 LADP 目錄中任何地點(diǎn)的靈活性。稍后在本文中,您將了解如何配置 Acegi 以應(yīng)用 specialUser

    使用專有名稱

    LDAP 使用專有名稱(DN)的概念來(lái)識(shí)別 LDAP 樹上特定的節(jié)點(diǎn)。每個(gè)節(jié)點(diǎn)具有惟一的 DN,它包含該節(jié)點(diǎn)完整的層次結(jié)構(gòu)信息。例如,圖 2 展示了圖 1 中的一些節(jié)點(diǎn)的 DN:


    圖 2. LDAP 目錄節(jié)點(diǎn)的專有名稱
    圖 2. LDAP 目錄節(jié)點(diǎn)的專有名稱

    首先,注意圖 2 中根節(jié)點(diǎn)的 DN。它的 DN 為 dc=org,這是與 org 根節(jié)點(diǎn)相關(guān)的屬性值對(duì)。每個(gè)節(jié)點(diǎn)都有若干個(gè)與之相關(guān)的屬性。dc 屬性代表 “domain component” 并由 LDAP RFC 2256 定義(參見 參考資料 中有關(guān)官方 RFC 文檔的鏈接),LDAP 目錄中的根節(jié)點(diǎn)通常表示為一個(gè)域組件。

    每個(gè) LDAP 屬性是由 RFC 定義的。LDAP 允許使用多個(gè)屬性創(chuàng)建一個(gè) DN,但是本文的示例只使用了以下 4 個(gè)屬性:

    • dc(域組件)
    • o(組織)
    • ou(組織單元)
    • uid(用戶 ID)

    示例使用 dc 表示域,用 o 表示組織名稱,ou 表示組織的不同單元,而 uid 表示用戶。

    由于 org 是根節(jié)點(diǎn),其 DN 只需指定自身的名稱(dc=org)。比較一下,manufacturingEnterprise 節(jié)點(diǎn)的 DN 是 o=manufacturingEnterprise,dc=org。當(dāng)向下移動(dòng)節(jié)點(diǎn)樹時(shí),每個(gè)父節(jié)點(diǎn)的 DN 被包含在其子節(jié)點(diǎn)的 DN 中。

    將屬性分組

    LDAP 將相關(guān)的屬性類型分到對(duì)象類中。例如,名為 organizationalPerson 的對(duì)象類所包含的屬性定義了在組織內(nèi)工作的人員(例如,職稱、常用名、郵寄地址等等)。

    對(duì)象類使用繼承特性,這意味著 LDAP 定義了基類來(lái)保存常用屬性。然后子類再對(duì)基類進(jìn)行擴(kuò)展,使用其定義的屬性。LDAP 目錄中的單個(gè)節(jié)點(diǎn)可以使用若干個(gè)對(duì)象類:本文的示例使用了以下幾個(gè)對(duì)象類:

    • top 對(duì)象類是 LDAP 中所有對(duì)象類的基類。

    • 當(dāng)其他對(duì)象類都不適合某個(gè)對(duì)象時(shí),將使用 domain 對(duì)象類。它定義了一組屬性,任何一個(gè)屬性都可以用來(lái)指定一個(gè)對(duì)象。其 dc 屬性是強(qiáng)制性的。

    • organization 對(duì)象類表示組織節(jié)點(diǎn),例如 圖 2 中的 manufacturingEnterprise

    • organizationalUnit 對(duì)象類表示組織內(nèi)的單元,例如 圖 1 中的 departments 節(jié)點(diǎn)及其子節(jié)點(diǎn)。

    • groupOfNames 對(duì)象類表示一組名稱,例如某部門職員的名稱。它具有一個(gè) member 屬性,該屬性包含一個(gè)用戶列表。圖 1 中所有的組節(jié)點(diǎn)(例如 engineers 節(jié)點(diǎn))使用 member 屬性指定該組的成員。而且,示例使用 groupOfNames 對(duì)象類的 ou(組織單元)屬性指定組用戶的業(yè)務(wù)角色。

    • organizationalPerson 對(duì)象類表示組織內(nèi)某個(gè)職員(例如 圖 1 中的 alice 節(jié)點(diǎn))。




    回頁(yè)首


    使用 LDAP 服務(wù)器

    在真實(shí)的應(yīng)用程序中,通常將有關(guān)系統(tǒng)用戶的大量信息托管在一個(gè) LDAP 目錄中。例如,將存儲(chǔ)每個(gè)用戶的用戶名、密碼、職稱、聯(lián)系方式和工資信息。為簡(jiǎn)單起見,下面的例子將只向您展示如何保存用戶名和密碼。

    如前所述,示例使用 ApacheDS(一種開源的 LDAP 目錄服務(wù)器)演示了 Acegi 是如何使用 LDAP 目錄的。示例還使用了一個(gè)開源的 LDAP 客戶機(jī)(名為 JXplorer)執(zhí)行簡(jiǎn)單的目錄操作,例如將信息托管在 ApacheDS 上。參見 參考資料 以下載 ApacheDS、JXplorer 并了解更多有關(guān)兩者協(xié)作的信息。

    在 ApacheDS 創(chuàng)建一個(gè)根節(jié)點(diǎn)

    要?jiǎng)?chuàng)建 圖 1 所示的節(jié)點(diǎn)樹,必須首先在 ApacheDS 中創(chuàng)建一個(gè)根節(jié)點(diǎn) org。ApacheDS 為此提供了一個(gè) XML 配置文件。XML 配置文件定義了一組可進(jìn)行配置的 bean,從而根據(jù)應(yīng)用程序的需求定制目錄服務(wù)器的行為。本文只解釋創(chuàng)建根節(jié)點(diǎn)所需的配置。

    可以在 ApacheDS 安裝中的 conf 文件夾找到名為 server.xml 的 XML 配置文件。打開文件后,會(huì)發(fā)現(xiàn)很多 bean 配置類似于 Acegi 的過濾器配置。查找名為 examplePartitionsConfiguration 的 bean。該 bean 控制 ApacheDS 上的分區(qū)。當(dāng)創(chuàng)建新的根節(jié)點(diǎn)時(shí),實(shí)際上將在 LDAP 目錄上創(chuàng)建一個(gè)新的分區(qū)。

    編輯 examplePartitionConfiguration bean 以創(chuàng)建 org 根節(jié)點(diǎn),如清單 1 所示:


    清單 1. 編輯模式的 examplePartitionConfiguration bean 配置
                            <bean id="examplePartitionConfiguration" class=
                "org.apache.directory.server.core.partition.impl.btree.MutableBTreePartitionConfiguration"
                >
                <property name="suffix"><value>dc=org</value></property>
                <property name="contextEntry">
                <value>
                objectClass: top
                objectClass: domain
                dc: org
                </value>
                </property>
                <!-- Other properties of the examplePartitionConfiguration bean, which you don't
                need to edit. -->
                </bean>
                

    清單 1 編輯了 examplePartitionConfiguration bean 的兩個(gè)屬性:

    • 一個(gè)屬性名為 suffix,它定義根條目的 DN。

    • 另一個(gè)屬性名為 contextEntry,定義 org 節(jié)點(diǎn)將使用的對(duì)象類。注意,org 根節(jié)點(diǎn)使用兩個(gè)對(duì)象類:topdomain

    本文的 源代碼下載 部分包含了編輯模式的 server.xml 文件。如果希望繼續(xù)學(xué)習(xí)本示例,請(qǐng)將 server.xml 文件從源代碼中復(fù)制到您的 ApacheDS 安裝目錄中的正確位置,即 conf 文件夾。

    圖 3 所示的屏幕截圖展示了在 ApacheDS 中創(chuàng)建根節(jié)點(diǎn)后,JXplorer 是如何顯示該根節(jié)點(diǎn)的:


    圖 3. JXplorer 顯示根節(jié)點(diǎn)
    圖 3. JXplorer 顯示根節(jié)點(diǎn)

    填充服務(wù)器

    設(shè)置 LDAP 服務(wù)器的下一步是使用用戶和組信息填充服務(wù)器。您可以使用 JXplorer 在 ApacheDS 中逐個(gè)創(chuàng)建節(jié)點(diǎn),但是使用 LDAP Data Interchange Format (LDIF) 填充服務(wù)器會(huì)更加方便。LDIF 是可被大多數(shù) LDAP 實(shí)現(xiàn)識(shí)別的常見格式。developerWorks 文章很好地介紹了 LDIF 文件的內(nèi)容,因此本文將不再做詳細(xì)說(shuō)明。(參見 參考資料 中有關(guān) LDIF 的詳細(xì)資料。)

    您可以在 源代碼下載 部分查看 LDIF 文件,它表示 圖 1 所示的用戶和部門。您可以使用 JXplorer 將 LDIF 文件導(dǎo)入到 ApacheDS。要導(dǎo)入 LDIF 文件,在 JXplorer 中使用 LDIF 菜單,如圖 4 所示:


    圖 4. 將 LDIF 文件導(dǎo)入到 ApacheDS
    圖 4. 將 LDIF 文件導(dǎo)入到 ApacheDS

    將 LDIF 文件導(dǎo)入到 ApacheDS 之后,JXplorer 將顯示用戶節(jié)點(diǎn)和部門節(jié)點(diǎn)樹,如 圖 1 所示。現(xiàn)在您可以開始配置 Acegi,使其能夠與您的 LDAP 服務(wù)器通信。





    回頁(yè)首


    為 LDAP 實(shí)現(xiàn)配置 Acegi

    回想一下第 1 部分,其中 Acegi 使用身份驗(yàn)證處理過濾器(Authentication Processing Filter,APF)進(jìn)行身份驗(yàn)證。APF 執(zhí)行所有后端身份驗(yàn)證處理任務(wù),例如從客戶機(jī)請(qǐng)求中提取用戶名和密碼,從后端用戶庫(kù)讀取用戶參數(shù),以及使用這些信息對(duì)用戶進(jìn)行身份驗(yàn)證。

    您在第 1 部分中為屬性文件實(shí)現(xiàn)配置了 APF,現(xiàn)在您已將用戶庫(kù)存儲(chǔ)在 LDAP 目錄中,因此必須使用不同的方式配置過濾器來(lái)和 LDAP 目錄進(jìn)行通信。首先看一下清單 2,它展示了在第 1 部分中的 “Authentication Processing Filter” 一節(jié)中如何為屬性文件實(shí)現(xiàn)配置 APF 過濾器:


    清單 2. 為屬性文件配置 APF
                            <bean id="authenticationProcessingFilter"
                class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
                <property name="authenticationManager" ref="authenticationManager" />
                <property name="authenticationFailureUrl"
                value="/login.jsp?login_error=1" />
                <property name="defaultTargetUrl"
                value="/index.jsp" />
                <property name="filterProcessesUrl"
                value="/j_acegi_security_check" />
                </bean>
                

    查看一下清單 2,您曾經(jīng)為 APF 提供了 4 個(gè)參數(shù)。您只需在 LDAP 服務(wù)器中為存儲(chǔ)重新配置第一個(gè)參數(shù)(authenticationManager)即可。其他三個(gè)參數(shù)保持不變。

    配置身份驗(yàn)證管理器

    清單 3 展示了如何配置 Acegi 的身份驗(yàn)證管理器,以實(shí)現(xiàn)與 LDAP 服務(wù)器的通信:


    清單 3. 為 LDAP 配置 Acegi 的身份驗(yàn)證管理器
                            <bean id="authenticationManager"
                class="org.acegisecurity.providers.ProviderManager">
                <property name="providers">
                <list>
                <ref local="ldapAuthenticationProvider" />
                </list>
                </property>
                </bean>
                

    在清單 3 中,org.acegisecurity.providers.ProviderManager 是一個(gè)管理器類,它管理 Acegi 的身份驗(yàn)證過程。為此,身份驗(yàn)證管理器需要一個(gè)或多個(gè)身份驗(yàn)證提供者。您可以使用管理器 bean 的提供者屬性來(lái)配置一個(gè)或多個(gè)提供者。清單 3 只包含了一個(gè)提供者,即 LDAP 身份驗(yàn)證提供者。

    LDAP 身份驗(yàn)證提供者處理所有與后端 LDAP 目錄的通信。您必須對(duì)其進(jìn)行配置,下一節(jié)內(nèi)容將討論該主題。

    配置 LDAP 身份驗(yàn)證提供者

    清單 4 展示了 LDAP 身份驗(yàn)證提供者的配置:


    清單 4. 配置 LDAP 身份驗(yàn)證提供者
                            <bean id="ldapAuthenticationProvider"
                class="org.acegisecurity.providers.ldap.LdapAuthenticationProvider">
                <constructor-arg><ref local="authenticator"/></constructor-arg>
                <constructor-arg><ref local="populator"/></constructor-arg>
                </bean>
                

    注意 LDAP 身份驗(yàn)證提供者類的名稱為 org.acegisecurity.providers.ldap.LdapAuthenticationProvider 。其構(gòu)造函數(shù)包含兩個(gè)參數(shù),使用兩個(gè) <constructor-arg> 標(biāo)記的形式,如清單 4 所示。

    LdapAuthenticationProvider 構(gòu)造函數(shù)的第一個(gè)參數(shù)是 authenticator,該參數(shù)通過檢查用戶的用戶名和密碼對(duì) LDAP 目錄的用戶進(jìn)行身份驗(yàn)證。完成身份驗(yàn)證后,第二個(gè)參數(shù) populator 將從 LDAP 目錄中檢索有關(guān)該用戶的訪問權(quán)限(或業(yè)務(wù)角色)信息。

    以下小節(jié)將向您展示如何配置驗(yàn)證器和填充器 bean。





    回頁(yè)首


    配置驗(yàn)證器

    authenticator bean 將檢查具有給定用戶名和密碼的用戶是否存在于 LDAP 目錄中。Acegi 提供了名為 org.acegisecurity.providers.ldap.authenticator.BindAuthenticator 的驗(yàn)證器類,它將執(zhí)行驗(yàn)證用戶名和密碼所需的功能。

    配置 authenticator bean,如清單 5 所示:


    清單 5. 配置驗(yàn)證器 bean
                            <bean id="authenticator"
                class="org.acegisecurity.providers.ldap.authenticator.BindAuthenticator">
                <constructor-arg><ref local="initialDirContextFactory"/></constructor-arg>
                <property name="userDnPatterns">
                <list>
                <value>uid={0},ou=employees,ou=partners</value>
                <value>uid={0},ou=customers,ou=partners</value>
                <value>uid={0},ou=suppliers,ou=partners</value>
                </list>
                </property>
                <property name="userSearch"><ref local="userSearch"/></property>
                </bean>
                

    在清單 5 中,BindAuthenticator 構(gòu)造函數(shù)具有一個(gè)參數(shù),使用 <constructor-arg> 標(biāo)記的形式。清單 5 中參數(shù)的名稱為 initialDirContextFactory。該參數(shù)實(shí)際上是另一個(gè) bean,稍后您將學(xué)習(xí)如何配置該 bean。

    目前為止,只知道 initialDirContextFactory bean 的作用就是為稍后的搜索操作指定初始上下文。初始上下文是一個(gè) DN,它指定了 LDAP 目錄內(nèi)某個(gè)節(jié)點(diǎn)。指定初始上下文后,將在該節(jié)點(diǎn)的子節(jié)點(diǎn)中執(zhí)行所有的搜索操作(例如查找特定用戶)。

    例如,回到 圖 2 中查看 partners 節(jié)點(diǎn),它的 DN 是 ou=partners,o=manufacturingEnterprise,dc=org。如果將 partners 節(jié)點(diǎn)指定為初始上下文,Acegi 將只在 partners 節(jié)點(diǎn)的子節(jié)點(diǎn)中查找用戶。

    指定 DN 模式

    除配置 BindAuthenticator 構(gòu)造函數(shù)外,還必須配置 authenticator bean 的兩個(gè)屬性(清單 5 中的兩個(gè) <property> 標(biāo)記)。

    第一個(gè) <property> 標(biāo)記定義了一個(gè) userDnPatterns 屬性,它封裝了一個(gè)或多個(gè) DN 模式列表。DN 模式 指定了一組具有類似特性的 LDAP 節(jié)點(diǎn)(例如 圖 2 所示的 employees 節(jié)點(diǎn)的所有子節(jié)點(diǎn))。

    Acegi 的身份驗(yàn)證器從 authenticator bean 的 userDnPatterns 屬性中配置的每個(gè) DN 模式構(gòu)造了一個(gè) DN。例如,查看 清單 5 中配置的第一個(gè)模式,即 uid={0},ou=employees,ou=partners。在進(jìn)行身份驗(yàn)證的時(shí)候,authenticator bean 使用用戶提供的用戶名(比如 alice)替換了 {0}。使用用戶名取代了 {0} 之后,DN 模式將變?yōu)橄鄬?duì) DN(RDN)uid=alice,ou=employees,ou=partners,它需要一個(gè)初始上下文才能成為 DN。

    例如,查看 圖 2 中的 alice's 條目。該條目是 employees 節(jié)點(diǎn)的第一個(gè)子節(jié)點(diǎn)。它的 DN 是 uid=alice,ou=employees,ou=partners,o=manufacturingEnterprise, dc=org。如果使用 o=manufacturingEnterprise,dc=org 作為初始上下文并將其添加到 RDN uid=alice,ou=employees,ou=partners 之后,將獲得 alice 的 DN。

    使用這種方法通過 DN 模式構(gòu)建了用戶的 DN 后,authenticator 將把 DN 和用戶密碼發(fā)送到 LDAP 目錄。目錄將檢查該 DN 是否具有正確的密碼。如果有的話,用戶就可以通過身份驗(yàn)證。這個(gè)過程在 LDAP 術(shù)語(yǔ)中被稱為 bind 身份驗(yàn)證。LDAP 還提供了其他類型的身份驗(yàn)證機(jī)制,但是本文的示例只使用了 bind 身份驗(yàn)證。

    如果目錄中并沒有第一個(gè) DN 模式創(chuàng)建的 DN,authenticator bean 嘗試使用列表中配置的第二個(gè) DN 模式。依此類推,authenticator bean 將嘗試所有的 DN 模式來(lái)為進(jìn)行身份驗(yàn)證的用戶構(gòu)造正確的用戶 DN。

    搜索過濾器

    回想一下較早的章節(jié) “LDAP 目錄設(shè)置”,我在將用戶信息存儲(chǔ)到 LDAP 目錄時(shí)添加了一點(diǎn)靈活性。方法是在 圖 1 所示的 departments 節(jié)點(diǎn)內(nèi)創(chuàng)建一個(gè)特定用戶(specialUser)。

    如果試圖使用 清單 5 中配置的任何一種 DN 模式創(chuàng)建特定用戶的 DN,您會(huì)發(fā)現(xiàn)沒有一種 DN 模式可用。因此,當(dāng)用戶嘗試登錄時(shí),Acegi 的 authenticator bean 將不能夠構(gòu)造正確的 DN,從而無(wú)法對(duì)該用戶進(jìn)行身份驗(yàn)證。

    通過允許您指定搜索過濾器,Acegi 能夠處理類似的特殊情況。身份驗(yàn)證器 bean 使用搜索過濾器查找不能夠通過 DN 模式構(gòu)造 DN 進(jìn)行身份驗(yàn)證的用戶。

    清單 5 中的第二個(gè) <property> 標(biāo)記具有一個(gè) <ref> 子標(biāo)記,它引用名為 userSearch 的 bean。userSearch bean 指定搜索查詢。清單 6 展示了如何配置 userSearch bean 來(lái)處理特定用戶:


    清單 6. 配置搜索查詢以搜索特定用戶
                            <bean id="userSearch"
                class="org.acegisecurity.ldap.search.FilterBasedLdapUserSearch">
                <constructor-arg>
                <value>ou=departments</value>
                </constructor-arg>
                <constructor-arg>
                <value>(uid={0})</value>
                </constructor-arg>
                <constructor-arg>
                <ref local="initialDirContextFactory" />
                </constructor-arg>
                <property name="searchSubtree">
                <value>true</value>
                </property>
                </bean>
                

    搜索查詢的參數(shù)

    清單 6 展示了 userSearch bean 是 org.acegisecurity.ldap.search.FilterBasedLdapUserSearch 類的一個(gè)實(shí)例,該類的構(gòu)造函數(shù)具有三個(gè)參數(shù)。第一個(gè)參數(shù)指定 authenticator 在哪個(gè)節(jié)點(diǎn)中搜索用戶。第一個(gè)參數(shù)的值為 ou=departments,該值是一個(gè) RDN,指定了 圖 2 所示的 departments 節(jié)點(diǎn)。

    第二個(gè)參數(shù) (uid={0}) 指定了一個(gè)搜索過濾器。由于使用 uid 屬性指定用戶,因此可以通過查找 uid 屬性具有特定值的節(jié)點(diǎn)來(lái)查找用戶。正如您所料,花括號(hào)里面的 0 向 Acegi 表示使用進(jìn)行身份驗(yàn)證的用戶的用戶名(本例中為 specialUser)替換 {0}

    第三個(gè)參數(shù)是對(duì)討論 清單 5 中的 BindAuthenticator 構(gòu)造函數(shù)時(shí)引入的相同初始上下文的引用。回想一下,當(dāng)指定了初始上下文后,稍后將在該初始上下文節(jié)點(diǎn)的子節(jié)點(diǎn)內(nèi)進(jìn)行所有的搜索操作。注意,應(yīng)將指定為 清單 5 中第一個(gè)參數(shù)(ou=departments)的值的 RDN 前加到初始上下文。

    除了這三個(gè)構(gòu)造器參數(shù),清單 6 所示的 userSearch bean 還具有一個(gè)名為 searchSubtree 的屬性。如果將其值指定為 true,搜索操作將包括節(jié)點(diǎn)的子樹(即所有子節(jié)點(diǎn)、孫節(jié)點(diǎn)、孫節(jié)點(diǎn)的子節(jié)點(diǎn)等),該節(jié)點(diǎn)被指定為構(gòu)造函數(shù)的第一個(gè)參數(shù)的值。

    authenticator bean 的配置完成后,下一步將查看 populator bean 的配置,如 清單 4 所示。





    回頁(yè)首


    配置 populator

    populator bean 將讀取已經(jīng)通過 authenticator bean 身份驗(yàn)證的用戶的業(yè)務(wù)角色。清單 7 展示 populator bean 的 XML 配置:


    清單 7. populator bean 的 XML 配置
                            <bean id="populator"
                class="org.acegisecurity.providers.ldap.populator.DefaultLdapAuthoritiesPopulator">
                <constructor-arg>
                <ref local="initialDirContextFactory"/>
                </constructor-arg>
                <constructor-arg>
                <value>ou=departments</value>
                </constructor-arg>
                <property name="groupRoleAttribute">
                <value>ou</value>
                </property>
                <property name="searchSubtree">
                <value>true</value>
                </property>
                </bean>
                

    在清單 7 中,populator bean 的構(gòu)造函數(shù)包括 2 個(gè)參數(shù),以及一個(gè) groupRoleAttribute 屬性。構(gòu)造函數(shù)的第一個(gè)參數(shù)指定了 populator bean 用來(lái)讀取經(jīng)過驗(yàn)證用戶的業(yè)務(wù)角色的初始上下文。并不強(qiáng)制要求 authenticatorpopulator bean 使用相同的初始上下文。您可以為這兩者分別配置一個(gè)初始上下文。

    第二個(gè)構(gòu)造函數(shù)參數(shù)指定了 populator 前加到初始上下文的 RDN。因此,RDN 組成了包含組用戶的節(jié)點(diǎn)的 DN,例如 departments 節(jié)點(diǎn)。

    populator bean 的 groupRoleAttribute 屬性指定了持有組成員業(yè)務(wù)角色數(shù)據(jù)的屬性。回想 設(shè)置 LDAP 目錄 一節(jié)中,您將每組用戶的業(yè)務(wù)角色信息存儲(chǔ)在名為 ou 的屬性中。然后將 ou 設(shè)置為 groupRoleAttribute 屬性的值,如 清單 7 所示。

    如您所料,populator bean 將搜索整個(gè) LDAP 目錄來(lái)查找經(jīng)過驗(yàn)證的用戶所屬的組節(jié)點(diǎn)。然后讀取組節(jié)點(diǎn)的 ou 屬性的值,獲取用戶經(jīng)過授權(quán)的業(yè)務(wù)角色。

    這樣就完成了 populator bean 的配置。目前為止,我們?cè)谌齻€(gè)位置使用了初始上下文:清單 5清單 6清單 7。接下來(lái)將了解如何配置初始上下文。

    配置初始上下文

    清單 8 展示了在 Acegi 中配置初始上下文的過程:


    清單 8. 初始上下文的 XML 配置
                            <bean id="initialDirContextFactory"
                class="org.acegisecurity.ldap.DefaultInitialDirContextFactory">
                <constructor-arg value="ldap://localhost:389/o=manufacturingEnterprise,dc=org"/>
                <property name="managerDn">
                <value>cn=manager,o=manufacturingEnterprise,dc=org</value>
                </property>
                <property name="managerPassword">
                <value>secret</value>
                </property>
                </bean>
                

    清單 8 中 Acegi 的初始上下文類的名稱為 org.acegisecurity.ldap.DefaultInitialDirContextFactory,這是 Acegi 包含的工廠類。Acegi 在內(nèi)部使用該類構(gòu)造其他處理目錄操作(例如在整個(gè)目錄中搜索)的類的對(duì)象。當(dāng)配置初始上下文工廠時(shí),必須指定以下內(nèi)容:

    • 將您的 LDAP 目錄和根目錄節(jié)點(diǎn)的網(wǎng)絡(luò)地址指定為構(gòu)造函數(shù)的參數(shù)。在初始上下文配置的節(jié)點(diǎn)將作為根節(jié)點(diǎn)。就是說(shuō)所有后續(xù)操作(例如 search)都將在根節(jié)點(diǎn)定義的子樹中執(zhí)行。

    • 將 DN 和密碼分別定義為 managerDnmanagerPassword 屬性。在執(zhí)行任何搜索操作之前,Acegi 必須使用目錄服務(wù)器對(duì) DN 和密碼進(jìn)行身份驗(yàn)證。

    您已經(jīng)了解了如何將用戶庫(kù)托管在 LDAP 目錄中,以及如何配置 Acegi 來(lái)使用來(lái)自 LDAP 目錄的信息對(duì)用戶進(jìn)行身份驗(yàn)證。下一節(jié)將進(jìn)一步介紹 Acegi 的身份驗(yàn)證處理過濾器,了解新配置的 bean 是如何管理身份驗(yàn)證過程的。





    回頁(yè)首


    身份驗(yàn)證和授權(quán)

    APF 配置完成后,將能夠與 LDAP 目錄進(jìn)行通信來(lái)對(duì)用戶進(jìn)行身份驗(yàn)證。如果您閱讀過第 1 部分,那么對(duì)與目錄通信過程中 APF 執(zhí)行的一些步驟不會(huì)感到陌生,我在第 1 部分中向您展示了過濾器如何使用不同的服務(wù)進(jìn)行用戶身份驗(yàn)證。圖 5 所示的序列表與您在 第 1 部分圖 3 看到的非常類似:


    圖 5. APF 對(duì)一名 LDAP 用戶進(jìn)行身份驗(yàn)證
    圖 5. APF 對(duì)一名 LDAP 用戶進(jìn)行身份驗(yàn)證

    無(wú)論 APF 使用屬性文件進(jìn)行內(nèi)部的身份驗(yàn)證還是與 LDAP 服務(wù)器進(jìn)行通信,步驟 1 到步驟 9 與第 1 部分是相同的。這里簡(jiǎn)單描述了前 9 個(gè)步驟,您可以從步驟 10 開始繼續(xù)學(xué)習(xí)特定于 LDAP 的事件:

    1. 過濾器鏈前面的過濾器將請(qǐng)求、響應(yīng)和過濾器鏈對(duì)象傳遞給 APF。

    2. APF 使用取自請(qǐng)求對(duì)象的用戶名、密碼和其他信息創(chuàng)建一個(gè)身份驗(yàn)證標(biāo)記。

    3. APF 將身份驗(yàn)證標(biāo)記傳遞給身份驗(yàn)證管理器。

    4. 身份驗(yàn)證管理器可能包含一個(gè)或多個(gè)身份驗(yàn)證提供者。每個(gè)提供者恰好支持一種身份驗(yàn)證類型。管理器將檢查哪一種提供者支持從 APF 接收到的身份驗(yàn)證標(biāo)記。

    5. 身份驗(yàn)證管理器將身份驗(yàn)證標(biāo)記傳遞給適合該類型身份驗(yàn)證的提供者。

    6. 身份驗(yàn)證提供者從身份驗(yàn)證標(biāo)記中提取用戶名并將其傳遞到名為 user cache service 的服務(wù)。Acegi 緩存了已經(jīng)進(jìn)行過身份驗(yàn)證的用戶。該用戶下次登錄時(shí),Acegi 可以從緩存中加載他或她的詳細(xì)信息(比如用戶名、密碼和權(quán)限),而不是從后端數(shù)據(jù)存儲(chǔ)中讀取數(shù)據(jù)。這種方法使得性能得到了改善。

    7. user cache service 檢查用戶的詳細(xì)信息是否存在于緩存中。

    8. user cache service 將用戶的詳細(xì)信息返回給身份驗(yàn)證提供者。如果緩存不包含用戶詳細(xì)信息,則返回 null。

    9. 身份驗(yàn)證提供者檢查緩存服務(wù)返回的是用戶的詳細(xì)信息還是 null。

    10. 從這里開始,身份驗(yàn)證處理將特定于 LDAP。 如果緩存返回 null,LDAP 身份驗(yàn)證提供者將把用戶名(在步驟 6 中提取的)和密碼傳遞給 清單 5 中配置的 authenticator bean。

    11. authenticator 將使用在 清單 5userDnPatterns 屬性中配置的 DN 模式創(chuàng)建用戶 DN。通過從一個(gè) DN 模式中創(chuàng)建一個(gè) DN,然后將該 DN 和用戶密碼(從用戶請(qǐng)求中獲得)發(fā)送到 LDAP 目錄,它將逐一嘗試所有可用的 DN 模式。LDAP 目錄將檢查該 DN 是否存在以及密碼是否正確。如果其中任何一個(gè) DN 模式可行的話,用戶被綁定到 LDAP 目錄中,authenticator 將繼續(xù)執(zhí)行步驟 15。

    12. 如果任何一種 DN 模式都不能工作的話(這意味著在 DN 模式指定的任何位置都不存在使用給定密碼的用戶),authenticator 根據(jù) 清單 6 配置的搜索查詢?cè)?LDAP 目錄中搜索用戶。如果 LDAP 目錄沒有找到用戶,那么身份驗(yàn)證以失敗告終。

    13. 如果 LDAP 目錄查找到了用戶,它將用戶的 DN 返回到 authenticator

    14. authenticator 將用戶 DN 和密碼發(fā)送到 LDAP 目錄來(lái)檢查用戶密碼是否正確。如果 LDAP 目錄發(fā)現(xiàn)用戶密碼是正確的,該用戶將被綁定到 LDAP 目錄。

    15. authenticator 將用戶信息發(fā)送回 LDAP 身份驗(yàn)證提供者。

    16. LDAP 身份驗(yàn)證提供者將控制權(quán)傳遞給 populator bean。

    17. populator 搜索用戶所屬的組。

    18. LDAP 目錄將用戶角色信息返回給 populator

    19. populator 將用戶角色信息返回給 LDAP 身份驗(yàn)證提供者。

    20. LDAP 身份驗(yàn)證提供者將用戶的詳細(xì)信息(以及用戶業(yè)務(wù)角色信息)返回給 APF。用戶現(xiàn)在成功進(jìn)行了身份驗(yàn)證。

    不論使用何種身份驗(yàn)證方法,最后三個(gè)步驟是相同的(步驟21、21 和 23)。

    配置攔截器

    您已經(jīng)了解了 APF 對(duì)用戶進(jìn)行身份驗(yàn)證的步驟。接下來(lái)是查看成功進(jìn)行身份驗(yàn)證的用戶是否被授權(quán)訪問所請(qǐng)求的資源。這項(xiàng)任務(wù)由 Acegi 的攔截過濾器(Interceptor Filter,IF)完成。本節(jié)將向您展示如何配置 IF 來(lái)實(shí)現(xiàn)訪問控制策略。

    回想一下在 第 1 部分的清單 7 中配置 IF 的步驟。攔截過濾器在資源和角色之間建立映射,就是說(shuō)只有具備必要角色的用戶才能訪問給定資源。為了演示制造業(yè)企業(yè)中不同部門的業(yè)務(wù)角色,清單 9 向現(xiàn)有的 IF 配置添加了另外的角色:


    清單 9. 配置攔截過濾器
                            <bean id="filterInvocationInterceptor"
                class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
                <property name="authenticationManager" ref="authenticationManager" />
                <property name="accessDecisionManager" ref="accessDecisionManager" />
                <property name="objectDefinitionSource">
                <value>
                CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
                PATTERN_TYPE_APACHE_ANT
                /protected/engineering/**=ROLE_HEAD_OF_ENGINEERING
                /protected/marketing/**=ROLE_HEAD_OF_MARKETING
                /**=IS_AUTHENTICATED_ANONYMOUSLY
                </value>
                </property>
                </bean>
                

    在清單 9 中,IF 包含三個(gè)參數(shù)。其中第一個(gè)和第三個(gè)參數(shù)與第 1 部分中最初配置的參數(shù)相同。這里添加了第二個(gè)參數(shù)(名為 accessDecisionManager 的 bean)。

    accessDecisionManager bean 負(fù)責(zé)指定授權(quán)決策。它使用清單 9 中第三個(gè)參數(shù)提供的訪問控制定義來(lái)指定授權(quán)(或訪問控制)決策。第三個(gè)參數(shù)是 objectDefinitionSource

    配置訪問決策管理器

    accessDecisionManager 決定是否允許一個(gè)用戶訪問某個(gè)資源。Acegi 提供了一些訪問決策管理器,它們指定訪問控制決策的方式有所不同。本文只解釋了其中一種訪問決策管理器的工作方式,其配置如清單 10 所示:


    清單 10. 配置訪問決策管理器
                            <bean id="accessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased">
                <property name="decisionVoters">
                <list>
                <bean class="org.acegisecurity.vote.RoleVoter"/>
                <bean class="org.acegisecurity.vote.AuthenticatedVoter" />
                </list>
                </property>
                </bean>
                

    在清單 10 中,accessDecisionManager bean 是 org.acegisecurity.vote.AffirmativeBased 類的實(shí)例。accessDecisionManager bean 只包含一個(gè)參數(shù),即投票者(voter)列表。

    在 Acegi 中,投票者確定是否允許某個(gè)用戶訪問特定的資源。當(dāng)使用 accessDecisionManager 查詢時(shí),投票者具有三個(gè)選項(xiàng):允許訪問(access-granted)、拒絕訪問(access-denied),如果不確定的話則放棄投票(abstain from voting)。

    不同類型的訪問決策管理器解釋投票者決策的方法也有所不同。清單 10 所示的 AffirmativeBased 訪問決策管理器實(shí)現(xiàn)了簡(jiǎn)單的決策邏輯:如果任何投票者強(qiáng)制執(zhí)行肯定投票,將允許用戶訪問所請(qǐng)求的資源。

    投票者邏輯

    Acegi 提供了若干個(gè)投票者實(shí)現(xiàn)類型。accessDecisionManager 將經(jīng)過驗(yàn)證的用戶的信息(包括用戶的業(yè)務(wù)角色信息)和 objectDefinitionSource 對(duì)象傳遞給投票者。本文的示例使用了兩種類型的投票者,RoleVoterAuthenticatedVoter,如清單 10 所示。現(xiàn)在看一下每種投票者的邏輯:

    • RoleVoter 只有在 objectDefinitionSource 對(duì)象的行中找到以 ROLE_ 前綴開頭的角色時(shí)才進(jìn)行投票。如果 RoleVoter 沒有找到這樣的行,將放棄投票;如果在用戶業(yè)務(wù)角色中找到一個(gè)匹配的角色,它將投票給允許訪問;如果沒有找到匹配的角色,則投票給拒絕訪問。在 清單 9 中,有兩個(gè)角色具有 ROLE_ 前綴:ROLE_HEAD_OF_ENGINEERINGROLE_HEAD_OF_MARKETING

    • AuthenticatedVoter 只有在 objectDefinitionSource 對(duì)象中找到具有某個(gè)預(yù)定義角色的行時(shí)才進(jìn)行投票。在 清單 9 中,有這樣一行:IS_AUTHENTICATED_ANONYMOUSLY。匿名身份驗(yàn)證意味著用戶不能夠進(jìn)行身份驗(yàn)證。找到該行后,AuthenticatedVoter 將檢查一個(gè)匿名身份驗(yàn)證的用戶是否可以訪問某些不受保護(hù)的資源(即這些資源沒有包含在具備 ROLE_ 前綴的行中)。如果 AuthenticatedVoter 發(fā)現(xiàn)所請(qǐng)求的資源是不受保護(hù)的并且 objectDefinitionSource 對(duì)象允許匿名身份驗(yàn)證的用戶訪問不受保護(hù)的資源,它將投票給允許訪問;否則就投票給拒絕訪問。




    回頁(yè)首


    示例應(yīng)用程序

    本文提供了一個(gè)示例應(yīng)用程序,它將演示您目前掌握的 LDAP 和 Acegi 概念。LDAP-Acegi 應(yīng)用程序?qū)@示一個(gè)索引頁(yè)面,該頁(yè)面將設(shè)計(jì)和銷售文檔呈現(xiàn)給合適的經(jīng)過身份驗(yàn)證的用戶。正如您將看到的一樣,LDAP-Acegi 應(yīng)用程序允許用戶 alice 查看設(shè)計(jì)文檔,并允許用戶 bob 查看銷售文檔。它還允許特定用戶同時(shí)查看設(shè)計(jì)和銷售文檔。所有這些內(nèi)容都是在本文開頭配置 LDAP 目錄服務(wù)器時(shí)設(shè)置的。立即 下載示例應(yīng)用程序 來(lái)開始使用它。





    回頁(yè)首


    結(jié)束語(yǔ)

    在本文中,您了解了如何將用戶和業(yè)務(wù)角色信息托管在 LDAP 目錄中。您還詳細(xì)了解了配置 Acegi 的方法,從而與 LDAP 目錄交互實(shí)現(xiàn)訪問控制策略。在本系列最后一期文章中,我將展示如何配置 Acegi 來(lái)保護(hù)對(duì) Java 類的訪問。



    來(lái)自:http://www.cnblogs.com/amboyna/archive/2008/03/25/1122084.html

    posted on 2008-05-08 18:43 狼愛上貍 閱讀(317) 評(píng)論(0)  編輯  收藏 所屬分類: Acegi

    主站蜘蛛池模板: 国产成人精品久久免费动漫| 91香蕉国产线观看免费全集| 免费无码一区二区三区蜜桃| 日本黄色动图免费在线观看| 人与禽交免费网站视频| 成人人观看的免费毛片| 最新69国产成人精品免费视频动漫 | 最新国产乱人伦偷精品免费网站| 亚洲国产精品无码久久久蜜芽 | 亚洲免费在线视频观看| 亚洲欧美日韩中文二区| 一级黄色免费网站| 中文字幕在线免费观看| 日韩免费视频播放| 亚洲国产精品无码久久久蜜芽 | 三年片免费观看大全国语| 91麻豆国产免费观看| 国产在线a不卡免费视频| 亚洲国产精品无码久久一线 | 久久精品国产亚洲AV网站| 亚洲av无码国产综合专区| 免费福利在线观看| 免费A级毛片无码A∨中文字幕下载| 天天天欲色欲色WWW免费| 亚洲欧洲精品成人久久奇米网 | 亚洲香蕉在线观看| 一级白嫩美女毛片免费| 久久成人国产精品免费软件| 免费在线观看视频a| 亚洲精品美女在线观看播放| 羞羞漫画页面免费入口欢迎你| 一级毛片在线免费观看| 成人伊人亚洲人综合网站222| 亚洲第一精品电影网| 亚洲一区二区影视| 一个人看的在线免费视频| 日本最新免费网站| 在线观看亚洲天天一三视| 亚洲国产成a人v在线观看| 三级网站在线免费观看| 色吊丝永久在线观看最新免费|