29. LDAP Authentication(LDAP身份驗證)


29.1 Overview

組織通常將LDAP用作用戶信息的中央存儲庫和身份驗證服務。它還可以用來存儲應用程序用戶的角色信息。

對於如何配置LDAP服務器有許多不同的場景,因此Spring Security的LDAP提供程序是完全可配置的。它使用獨立的策略接口進行身份驗證和角色檢索,並提供默認實現,可以配置這些實現來處理各種情況。

在嘗試將LDAP與Spring Security一起使用之前,您應該熟悉它。以下鏈接很好地介紹了相關概念,並提供了使用免費的LDAP服務器OpenLDAP建立目錄的指南:http://www.zytrax.com/books/ldap/.熟悉一些用於從Java訪問LDAP的JNDI應用編程接口可能也是有用的。我們不使用任何第三方LDAP庫(Mozilla、JLDAP等)。)中,但是Spring LDAP得到了廣泛的使用,所以如果您計划添加自己的定制,那么對該項目的一些熟悉可能會有所幫助。

使用LDAP身份驗證時,確保正確配置LDAP連接池非常重要。如果您不熟悉如何做到這一點,您可以參考Java LDAP文檔。

29.2 Using LDAP with Spring Security

Spring Security中的LDAP身份驗證可以大致分為以下幾個階段。

1、從登錄名中獲取唯一的LDAP“可分辨名稱”。這通常意味着在目錄中執行搜索,除非預先知道用戶名到DNs的確切映射。因此,用戶可能在登錄時輸入名稱“joe”,但是用於向LDAP進行身份驗證的實際名稱將是完整的DN,例如uid=joe,ou = users,dc=spring,dc=io。

2、通過將用戶“綁定”為該用戶或通過對用戶密碼與域名目錄條目中的密碼屬性執行遠程“比較”操作來驗證用戶身份

3、正在為用戶加載授權列表。

唯一的例外是,當LDAP目錄只是用來檢索用戶信息並在本地對其進行身份驗證時。這可能是不可能的,因為目錄通常設置為對屬性(如用戶密碼)具有有限的讀取權限。

我們將在下面看一些配置場景。有關可用配置選項的完整信息,請參考安全命名空間模式(這些信息應該在您的XML編輯器中提供)。

29.3 Configuring an LDAP Server

您需要做的第一件事是配置應該進行身份驗證的服務器。這是使用安全命名空間中的< ldap-server >元素完成的。這可以配置為指向外部LDAP服務器,使用url屬性:

29.3.1 Using an Embedded Test Server(使用嵌入式測試服務器)

< ldap-server >元素也可以用來創建嵌入式服務器,這對測試和演示非常有用。在這種情況下,您可以在沒有url屬性的情況下使用它:


 

這里我們指定了目錄的根DIT應該是“dc=springframework,dc=org”,這是默認的。通過這種方式,名稱空間解析器將創建一個嵌入式Apache目錄服務器,並掃描類路徑中的任何LDIF文件,它將嘗試將這些文件加載到服務器中。您可以使用ldif屬性自定義此行為,該屬性定義了要加載的LDIF資源:


 

這使得用LDAP啟動和運行變得容易得多,因為一直使用外部服務器可能不方便。它還將用戶與連接Apache目錄服務器所需的復雜bean配置隔離開來。使用普通的Spring Beans,配置會更加混亂。您必須為您的應用程序提供必要的Apache目錄依賴項jar來使用。這些可以從LDAP示例應用程序中獲得。

29.3.2 Using Bind Authentication(使用綁定身份驗證)

這是最常見的LDAP身份驗證場景。


 

這個簡單的示例將通過在提供的模式中替換用戶登錄名並嘗試用登錄密碼作為該用戶進行綁定來獲取用戶的域名。如果您的所有用戶都存儲在目錄中的一個節點下,這是可以的。如果您希望配置一個LDAP搜索過濾器來定位用戶,您可以使用以下內容:

 


 

如果與上面的服務器定義一起使用,這將在DN ou =人員、dc=springframework、dc=org下使用user-search-filter屬性的值作為篩選器來執行搜索。同樣,用戶登錄名替換了篩選器名稱中的參數,因此它將搜索uid屬性等於用戶名的條目。如果沒有提供user-search-base,將從根執行搜索。

29.3.3 Loading Authorities

如何從LDAP目錄中的組加載權限由以下屬性控制。

1、group-search-base 定義目錄樹中應該執行組搜索的部分。

2、group-role-attribute 包含由組條目定義的機構名稱的屬性。默認為cn

3、group-search-filter 用於搜索組成員的過濾器。默認為uniqueMember={0},對應於組唯一名稱LDAP類。在這種情況下,替代參數是用戶的完整可分辨名稱。如果要篩選登錄名,可以使用參數{1}。

所以如果我們使用以下配置

 


 

並且成功地被認證為用戶“ben ”,則隨后的權限加載將在目錄條目下執行搜索ou=groups,dc=springframework,dc=org,查找包含帶值的唯一成員屬性的條目uid=ben,ou=people,dc=springframework,dc=org,默認情況下,機構名稱的前綴是ROLE _ 。您可以使用role-prefix屬性對此進行更改。如果您不想要任何前綴,請使用role-prefix="none"。有關加載權限的更多信息,請參見DefaultLdapAuthoritiesPopulator類的Javadoc。

29.4 Implementation Classes

我們上面使用的命名空間配置選項使用起來很簡單,比顯式使用Spring beans要簡潔得多。有些情況下,您可能需要知道如何在應用程序上下文中直接配置Spring Security LDAP。例如,您可能希望自定義某些類的行為。如果您喜歡使用名稱空間配置,那么您可以跳過這一節和下一節。

主要的LDAP提供程序類,LdapAuthenticationProvider,實際上並不做太多工作,而是將工作委托給另外兩個beans,一個LdapAuthenticator和一個LdapAuthoritiesPopulator,它們分別負責驗證用戶和檢索用戶的授權權限集。

29.4.1 LdapAuthenticator實現

驗證器還負責檢索任何所需的用戶屬性。這是因為屬性的權限可能取決於所使用的身份驗證類型。例如,如果綁定為用戶,可能需要使用用戶自己的權限來讀取它們。

Spring Security目前提供了兩種身份驗證策略:

    1、直接向LDAP服務器進行身份驗證(“綁定”身份驗證)。

     2、密碼比較,將用戶提供的密碼與存儲在存儲庫中的密碼進行比較。這可以通過檢索密碼屬性的值並在本地進行檢查來完成,也可以通過執行LDAP“比較”操作來完成,在該操作中,提供的密碼被傳遞給服務器進行比較,而實際的密碼值永遠不會被檢索到。

Common Functionality

在對用戶進行身份驗證(通過任何一種策略)之前,必須從提供給應用程序的登錄名中獲取可分辨名稱。這可以通過簡單的模式匹配(通過設置setUserDnPatterns數組屬性)或userSearch 搜索屬性來實現。對於DN模式匹配方法,使用標准的Java模式格式,登錄名將替換參數{0}。該模式應該是相對於配置的SpringSecurityContextSource將綁定到的DN的(有關這方面的更多信息,請參見連接到LDAP服務器一節)。例如,如果您使用的LDAP服務器的URL是LDAP://monkey machine . co . uk/dc=springframework,dc=org,並且具有模式uid={0},ou = greategies,則登錄名“gorilla”將映射到DN uid=gorilla,ou = greategies,DC = spring framework,dc=org將依次嘗試每個已配置的域名模式,直到找到匹配項。有關使用搜索的信息,請參見下面關於搜索對象的部分。也可以使用這兩種方法的組合——首先檢查模式,如果沒有找到匹配的域名,將使用搜索。

BindAuthenticator綁定驗證器

org . spring framework . security . LDAP . authentication包中的BindAuthenticator類實現了綁定身份驗證策略。它只是試圖作為用戶綁定。

PasswordComparisonAuthenticator(密碼比較身份驗證器)

類PasswordComparisonAuthenticator實現了密碼比較身份驗證策略。

29.4.2 Connecting to the LDAP Server

上面討論的beans必須能夠連接到服務器。它們都必須提供一個SpringSecurityContextSource,它是Spring LDAP的上下文源的擴展。除非您有特殊要求,否則您通常會配置一個DefaultSpringsecurityContextSource bean,該bean可以用您的LDAP服務器的網址來配置,也可以用“管理員”用戶的用戶名和密碼來配置,默認情況下,當綁定到服務器時會使用該用戶名和密碼(而不是匿名綁定)。有關更多信息,請閱讀這個類的Javadoc和Spring LDAP的抽象上下文源。

29.4.3 LDAP Search Objects(LDAP搜索對象)

通常需要比簡單的域名匹配更復雜的策略來定位目錄中的用戶條目。這可以封裝在一個LdapUserSearch實例中,該實例可以提供給認證器實現,例如,允許它們定位用戶。提供的實現是FilterBasedLdapUserSearch。

FilterBasedLdapUserSearch

這個bean使用一個LDAP過濾器來匹配目錄中的用戶對象。在Javadoc中解釋了這個過程,以便在JDK DirContext類中找到相應的搜索方法。如這里所解釋的,搜索過濾器可以被提供參數。對於此類,唯一有效的參數是{0},它將被替換為用戶的登錄名。

29.4.4 LdapAuthoritiesPopulator

成功驗證用戶后,LdapAuthenticationProvider將通過調用已配置的LDapauthenticationpopulator bean,嘗試為用戶加載一組權限。DefaultLdapAuthoritiesPopulator是一個實現,它將通過在目錄中搜索用戶所屬的組來加載權限(通常這些組groupOfNames 或groupOfUniqueNames )。如果您只想將LDAP用於身份驗證,但從不同的來源(如數據庫)加載權限,那么您可以提供自己的接口實現,並將其注入。

 

29.4.5 Spring Bean Configuration

使用我們在此討論的一些beans的典型配置可能如下所示:

 


 

這將設置提供程序訪問一個帶有以下網址的LDAP服務器:LDAP://monkey machine:389/DC = spring framework,dc=org。將通過嘗試用DN uid=<user-login-name>,ou=people,dc=springframework,dc=org綁定來執行身份驗證。身份驗證成功后,將通過使用默認篩選器(member=<user’s-DN>)在ou=groups,dc=springframework,dc=org下進行搜索,將角色分配給用戶。角色名稱將取自每個匹配的“ou”屬性。

要配置一個用戶搜索對象,該對象使用過濾器(uid=<user-login-name>)來代替DN模式(或除此之外),您需要配置以下bean

 


 

並通過設置BindAuthenticator bean的userSearch 屬性來使用它。然后,在嘗試綁定為該用戶之前,驗證者將調用搜索對象來獲取正確的用戶的域名。

29.4.6 LDAP Attributes and Customized UserDetails(LDAP屬性和自定義用戶詳細信息)

使用LdapAuthenticationProvider的身份驗證的最終結果與使用標准UserDetailsService接口的普通Spring Security身份驗證相同。UserDetails 對象被創建並存儲在返回的Authentication 對象中。與UserDetailsService一樣,一個常見的需求是能夠定制這個實現並添加額外的屬性。

當使用LDAP時,這些通常是用戶條目的屬性。UserDetails 對象的創建由提供者的UserDetailsContextMapper 策略控制,該策略負責將用戶對象映射到LDAP上下文數據和從LDAP上下文數據映射用戶對象:

 


 

只有第一種方法與身份驗證相關。如果您提供了此接口的一個實現,並將其注入到LdapAuthenticationProvider中,您就可以精確地控制用戶詳細信息對象的創建方式。第一個參數是Spring LDAP的DirContextOperations 一個實例,它允許您訪問在身份驗證期間加載的LDAP屬性。用戶名參數是用於進行身份驗證的名稱,最后一個參數是由已配置的LDAP authorities填充器(LdapAuthoritiesPopulator)為用戶加載的權限集合。

根據您使用的身份驗證類型,上下文數據的加載方式略有不同。使用綁定驗證器,從綁定操作返回的上下文將用於讀取屬性,否則將使用從配置的上下文源(ContextSource )獲得的標准上下文來讀取數據(當搜索被配置為定位用戶時,這將是搜索對象返回的數據)。

 

29.5 Active Directory Authentication(活動目錄身份驗證)

活動目錄支持它自己的非標准身份驗證選項,正常的使用模式不太適合標准的LDAP身份驗證提供程序。通常,身份驗證是使用域用戶名(以用戶@域的形式)執行的,而不是使用LDAP可分辨名稱。為了使這變得更容易,Spring Security 3.1有一個為典型的活動目錄設置定制的身份驗證提供程序。

29.5.1 ActiveDirectoryLdapAuthenticationProvider(活動目錄Ldap身份驗證提供程序)

配置活動目錄身份驗證提供程序(ActiveDirectoryLdapAuthenticationProvider )非常簡單。您只需要提供域名和提供服務器地址的LDAP網址[20]。示例配置如下所示:

 


 

請注意,不需要指定單獨的上下文源來定義服務器位置bean,它是完全獨立的。一個名叫“Sharon”的用戶。例如,將能夠通過輸入用戶名sharon或完整的Active Directory user principalname(即sharon@mydomain.com)進行身份驗證。然后將定位用戶的目錄條目,並返回屬性,以便在定制創建的用戶詳細信息對象時可能使用(可以為此目的注入用戶詳細信息文本映射器(UserDetailsContextMapper )),如上所述)。與目錄的所有交互都以用戶自身的身份進行。沒有“manager”用戶的概念。

默認情況下,用戶權限從用戶條目的成員屬性值(memberOf)中獲取。分配給用戶的權限也可以使用用戶詳細信息文本映射器(UserDetailsContextMapper)進行自定義。您還可以將授權授權映射器(GrantedAuthoritiesMapper )注入到提供程序實例中,以控制最終出現在身份驗證對象中的授權。

Active Directory Error Codes(活動目錄錯誤代碼)

默認情況下,失敗的結果將導致標准的spring安全不良證書異常(BadCredentialsException)。如果將屬性ConvertsuberrorCodeStoExceptions設置為true,將會分析異常消息,以嘗試提取特定於活動目錄的錯誤代碼並引發更特定的異常。有關更多信息,請查看Javadoc類。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM