配置

配置 Spring LDAP 的推薦方式是使用自定義 XML 配置名稱空間。要使其可用,您需要在 bean 檔案中包含 Spring LDAP 名稱空間宣告,如下所示

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:ldap="http://www.springframework.org/schema/ldap"
       xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/ldap https://www.springframework.org/schema/ldap/spring-ldap.xsd">

ContextSource 配置

ContextSource 透過使用 <ldap:context-source> 標籤定義。最簡單的 context-source 宣告需要指定伺服器 URL、使用者名稱和密碼,如下所示

示例 1. 最簡單的 context-source 宣告
<ldap:context-source
    username="cn=Administrator"
    password="secret"
    url="ldap://:389" />

前面的示例使用預設值(參見本段之後的表格)以及指定的 URL 和認證憑據建立一個 LdapContextSource 例項。context-source 上可配置的屬性如下(必選屬性用 * 標記)

表格 1. ContextSource 配置屬性
屬性 預設值 說明

id

contextSource

所建立 bean 的 ID。

username

用於在 LDAP 伺服器上進行認證的使用者名稱(主體)。這通常是管理員使用者的判別名(例如 cn=Administrator),但也可能因伺服器和認證方法而異。如果未明確配置 authentication-source-ref,則此項為必選。

password

用於在 LDAP 伺服器上進行認證的密碼(憑據)。如果未明確配置 authentication-source-ref,則此項為必選。

url *

要使用的 LDAP 伺服器 URL。URL 應採用以下格式:ldap://myserver.example.com:389。對於 SSL 訪問,請使用 ldaps 協議和相應的埠,例如 ldaps://myserver.example.com:636。如果需要故障轉移功能,可以指定多個 URL,用逗號(,)分隔。

base

LdapUtils.emptyLdapName()

基準 DN。配置此屬性後,提供給 LDAP 操作或從 LDAP 操作接收的所有判別名 (Distinguished Names) 都相對於指定的 LDAP 路徑。這可以顯著簡化對 LDAP 樹的操作。但是,在某些情況下,您可能需要訪問基準路徑,以便構建相對於 LDAP 樹實際根的完整 DN。一個例子是處理 LDAP 組(例如 groupOfNames 物件類)時。在這種情況下,每個組成員屬性值都需要是被引用成員的完整 DN。更多資訊請參見 獲取基準 LDAP 路徑的引用

anonymous-read-only

false

定義是否使用匿名(未認證)上下文執行只讀操作。請注意,將此引數設定為 true 並同時啟用補償性事務支援是不被支援的,並且會被拒絕。

referral

null

定義處理 referrals 的策略,如 這裡 所述。有效值包括

  • ignore

  • follow

  • throw

native-pooling

false

指定是否應使用原生的 Java LDAP 連線池。建議改用 Spring LDAP 連線池。更多資訊請參見 連線池支援

authentication-source-ref

一個 SimpleAuthenticationSource 例項。

要使用的 AuthenticationSource 例項的 ID(參見 自定義主體和憑據管理)。

authentication-strategy-ref

一個 SimpleDirContextAuthenticationStrategy 例項。

要使用的 DirContextAuthenticationStrategy 例項的 ID(參見 自定義 DirContext 認證處理)。

base-env-props-ref

對一個 Map 的引用,其中包含自定義環境屬性,應在構建 DirContext 時隨環境一起提供。

DirContext 認證

建立用於在 LDAP 伺服器上執行操作的 DirContext 例項時,這些上下文通常需要經過認證。Spring LDAP 提供了各種配置選項。

本節涉及在 ContextSource 的核心功能中認證上下文,以構建供 LdapClientLdapTemplate 使用的 DirContext 例項。LDAP 通常僅用於使用者認證,而 ContextSource 也可用於此目的。此過程在 使用 Spring LDAP 進行使用者認證 中討論。

預設情況下,只讀和讀寫操作都會建立已認證的上下文。您應在 context-source 元素上指定用於認證的 LDAP 使用者的 usernamepassword

如果 username 是 LDAP 使用者的判別名 (DN),則需要是該使用者從 LDAP 樹根開始的完整 DN,無論是否在 context-source 元素上指定了 base LDAP 路徑。

某些 LDAP 伺服器設定允許匿名只讀訪問。如果希望只讀操作使用匿名上下文,請將 anonymous-read-only 屬性設定為 true

自定義 DirContext 認證處理

Spring LDAP 中使用的預設認證機制是 SIMPLE 認證。這意味著主體(由 username 屬性指定)和憑據(由 password 指定)會被設定到傳送給 DirContext 實現建構函式的 Hashtable 中。

在許多情況下,此處理方式是不夠的。例如,LDAP 伺服器通常被設定為僅在安全的 TLS 通道上接受通訊。可能需要使用特定的 LDAP Proxy Auth 機制或其他考慮事項。

您可以透過向 context-source 元素提供 DirContextAuthenticationStrategy 實現引用來指定替代的認證機制。為此,請設定 authentication-strategy-ref 屬性。

TLS

Spring LDAP 為需要 TLS 安全通道通訊的 LDAP 伺服器提供了兩種不同的配置選項:DefaultTlsDirContextAuthenticationStrategyExternalTlsDirContextAuthenticationStrategy。這兩種實現都在目標連線上協商 TLS 通道,但在實際的認證機制上有所不同。DefaultTlsDirContextAuthenticationStrategy 在安全通道上應用 SIMPLE 認證(使用指定的 usernamepassword),而 ExternalTlsDirContextAuthenticationStrategy 使用 EXTERNAL SASL 認證,應用透過系統屬性配置的客戶端證書進行認證。

由於不同的 LDAP 伺服器實現對 TLS 通道的顯式關閉響應不同(有些伺服器要求優雅地關閉連線,而有些則不支援),TLS DirContextAuthenticationStrategy 實現支援透過使用 shutdownTlsGracefully 引數指定關閉行為。如果此屬性設定為 false(預設值),則不會發生顯式的 TLS 關閉。如果設定為 true,Spring LDAP 會嘗試在關閉目標上下文之前優雅地關閉 TLS 通道。

處理 TLS 連線時,需要確保原生的 LDAP 連線池功能(透過使用 native-pooling 屬性指定)已關閉。如果 shutdownTlsGracefully 設定為 false,這一點尤為重要。然而,由於 TLS 通道協商過程開銷較大,透過使用 Spring LDAP 連線池支援(在 連線池支援 中描述),可以獲得顯著的效能提升。

自定義主體和憑據管理

預設情況下,用於建立已認證 Context 的使用者名稱(即使用者 DN)和密碼是靜態定義的(在 context-source 元素配置中定義的將貫穿 ContextSource 的整個生命週期使用),但在某些情況下,這不是期望的行為。一個常見的場景是,在為當前使用者執行 LDAP 操作時,應使用該使用者的主體和憑據。您可以透過向 context-source 元素提供 AuthenticationSource 實現引用,而不是顯式指定 usernamepassword,來修改預設行為。ContextSource 會在每次需要建立已認證 Context 時查詢 AuthenticationSource 獲取主體和憑據。

如果您使用 Spring Security,可以透過使用 Spring Security 中提供的 SpringSecurityAuthenticationSource 例項配置您的 ContextSource,確保始終使用當前登入使用者的主體和憑據。以下示例展示瞭如何操作

示例 2. 使用 SpringSecurityAuthenticationSource
<beans>
...
    <ldap:context-source
        url="ldap://:389"
        authentication-source-ref="springSecurityAuthenticationSource"/>

    <bean id="springSecurityAuthenticationSource"
        class="org.springframework.security.ldap.authentication.SpringSecurityAuthenticationSource" />
...
</beans>
使用 AuthenticationSource 時,我們不為 context-source 指定任何 usernamepassword。這些屬性僅在使用預設行為時才需要。
使用 SpringSecurityAuthenticationSource 時,您需要使用 Spring Security 的 LdapAuthenticationProvider 對使用者進行 LDAP 認證。

原生 Java LDAP 連線池

內部 Java LDAP 提供程式提供了一些非常基礎的連線池功能。您可以透過在 AbstractContextSource 上使用 pooled 標誌來開啟或關閉此 LDAP 連線池。預設值為 false(自 1.3 版本起)— 也就是說,原生的 Java LDAP 連線池是關閉的。LDAP 連線池的配置是透過使用 System 屬性管理的,因此您需要在 Spring Context 配置之外手動處理。您可以在 這裡 找到原生連線池配置的詳細資訊。

內建的 LDAP 連線池存在幾個嚴重的缺陷,這就是 Spring LDAP 提供了更復雜的 LDAP 連線池方法的原因,詳見 連線池支援。如果您需要連線池功能,建議採用此方法。
無論連線池配置如何,ContextSource#getContext(String principal, String credentials) 方法始終明確不使用原生的 Java LDAP 連線池,以便重置的密碼能儘快生效。

高階 ContextSource 配置

本節介紹了配置 ContextSource 的更高階方法。

自定義 DirContext 環境屬性

在某些情況下,除了直接在 context-source 上可配置的屬性之外,您可能希望指定額外的環境設定屬性。您應在一個 Map 中設定此類屬性,並在 base-env-props-ref 屬性中引用它們。

LdapClient 配置

LdapClient 是用於呼叫 LDAP 後端的新介面。它在以下方面改進了 LdapTemplate

  • 提供內建的 Stream 支援

  • 提供一個圍繞 bind ©、search ®、modify (U)、unbind (D) 和 authenticate 的簡化 API。

LdapClient 尚未支援 ODM。如果您需要此功能,LdapTemplate 具有此能力。LdapClientLdapTemplate 在同一個應用程式中可以很好地共存,如果需要的話。

LdapClient 透過使用 LdapClient#create 工廠方法定義,如下所示

示例 3. 最簡單的 LdapClient 宣告
<bean id="ldapClient" class="org.springframework.ldap.core.LdapClient" factory-method="create">
   <constructor-arg ref="contextSource" />
</bean>

此元素引用了預設的 ContextSource,預期其 ID 為 contextSource(即 context-source 元素的預設值)。

您可以配置 LdapClient 例項如何處理某些已檢查異常以及任何預設的 SearchControls 應如何用於查詢。

LdapTemplate 配置

LdapTemplate 透過使用 <ldap:ldap-template> 元素定義。最簡單的 ldap-template 宣告就是元素本身

示例 4. 最簡單的 ldap-template 宣告
<ldap:ldap-template />

元素本身會建立一個 ID 為預設值、引用預設 ContextSourceLdapTemplate 例項,該 ContextSource 的 ID 預期為 contextSource(即 context-source 元素的預設值)。

以下表格描述了 ldap-template 上的可配置屬性

表格 2. LdapTemplate 配置屬性
屬性 預設值 說明

id

ldapTemplate

所建立 bean 的 ID。

context-source-ref

contextSource

要使用的 ContextSource 例項的 ID。

count-limit

0

搜尋的預設數量限制。0 表示無限制。

time-limit

0

搜尋的預設時間限制,單位為毫秒。0 表示無限制。

search-scope

SUBTREE

搜尋的預設搜尋範圍。有效值包括

  • OBJECT

  • ONELEVEL

  • SUBTREE

ignore-name-not-found

false

指定搜尋中是否應忽略 NameNotFoundException。將此屬性設定為 true 會使由無效搜尋基準引起的錯誤被靜默吞噬。

ignore-partial-result

false

指定搜尋中是否應忽略 PartialResultException。某些 LDAP 伺服器在處理 referrals 時存在問題。這些通常應自動跟隨。然而,如果不起作用,則會以 PartialResultException 的形式表現出來。將此屬性設定為 true 提供了一種解決此問題的方法。

odm-ref

要使用的 ObjectDirectoryMapper 例項的 ID。預設值是經過預設配置的 DefaultObjectDirectoryMapper

獲取基準 LDAP 路徑的引用

如前所述,您可以向 ContextSource 提供一個基準 LDAP 路徑,指定所有操作所相對於的 LDAP 樹的根。這意味著您的系統將始終使用相對判別名,這通常非常方便。但是,在某些情況下,您可能需要訪問基準路徑,以便能夠構建相對於 LDAP 樹實際根的完整 DN。一個例子是處理 LDAP 組(例如 groupOfNames 物件類)時。在這種情況下,每個組成員屬性值都需要是被引用成員的完整 DN。

因此,Spring LDAP 提供了一種機制,透過該機制,任何 Spring 管理的 bean 可以在啟動時獲得基準路徑。要使 bean 收到基準路徑通知,需要滿足兩個條件。首先,需要基準路徑引用的 bean 需要實現 BaseLdapNameAware 介面。其次,您需要在應用程式上下文中定義一個 BaseLdapPathBeanPostProcessor。以下示例展示瞭如何實現 BaseLdapNameAware

示例 5. 實現 BaseLdapNameAware
public class PersonService implements PersonService, BaseLdapNameAware {
   ...
   private LdapName basePath;

   public void setBaseLdapPath(LdapName basePath) {
      this.basePath = basePath;
   }
   ...
   private LdapName getFullPersonDn(Person person) {
      return LdapNameBuilder.newInstance(basePath)
          .add(person.getDn())
          .build();
   }
   ...
}

以下示例展示瞭如何定義 BaseLdapPathBeanPostProcessor

示例 6. 在 ApplicationContext 中指定 BaseLdapPathBeanPostProcessor
<beans>
   ...
   <ldap:context-source
          username="cn=Administrator"
          password="secret"
          url="ldap://:389"
          base="dc=261consulting,dc=com" />
   ...
   <bean class="org.springframework.ldap.core.support.BaseLdapPathBeanPostProcessor" />
</beans>

BaseLdapPathBeanPostProcessor 的預設行為是使用 ApplicationContext 中單個定義的 BaseLdapPathSource (AbstractContextSource) 的基準路徑。如果定義了多個 BaseLdapPathSource,則需要透過設定 baseLdapPathSourceName 屬性來指定使用哪一個。