組態

建議的 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://localhost:389" />

先前的範例會建立一個具有預設值的 LdapContextSource (請參閱本段落後的表格) 以及指定的 URL 和驗證憑證。context-source 上可組態的屬性如下 (必需屬性以 * 標記)

表 1. ContextSource 組態屬性
屬性 預設值 描述

id

contextSource

已建立 bean 的 ID。

username

當向 LDAP 伺服器驗證時要使用的使用者名稱 (principal)。這通常是管理員使用者的辨別名稱 (Distinguished Name) (例如,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 Name) 都相對於指定的 LDAP 路徑。這可以顯著簡化針對 LDAP 樹狀目錄的工作。但是,在某些情況下,您需要存取基礎路徑。有關此方面的更多資訊,請參閱 取得基礎 LDAP 路徑的參考

anonymous-read-only

false

定義是否使用匿名 (未驗證) context 執行唯讀操作。請注意,不支援將此參數設定為 true 以及補償交易支援,並且會被拒絕。

referral

null

定義處理 referral 的策略,如 此處 所述。有效值為

  • ignore

  • follow

  • throw

native-pooling

false

指定是否應使用原生 Java LDAP 連線池。考慮改為使用 Spring LDAP 連線池。請參閱 連線池支援 以取得更多資訊。

authentication-source-ref

SimpleAuthenticationSource 實例。

要使用的 AuthenticationSource 實例的 ID (請參閱 自訂 Principal 和憑證管理)。

authentication-strategy-ref

SimpleDirContextAuthenticationStrategy 實例。

要使用的 DirContextAuthenticationStrategy 實例的 ID (請參閱 自訂 DirContext 驗證處理)。

base-env-props-ref

對自訂環境屬性的 Map 的參考,這些屬性應與建構時傳送至 DirContext 的環境一起提供。

DirContext 驗證

當建立 DirContext 實例以用於在 LDAP 伺服器上執行操作時,這些 context 通常需要經過驗證。Spring LDAP 提供多種選項來組態此功能。

本節指的是在 ContextSource 的核心功能中驗證 context,以建構供 LdapClientLdapTemplate 使用的 DirContext 實例。LDAP 通常用於使用者驗證的唯一目的,而 ContextSource 也可用於此目的。該過程在 使用 Spring LDAP 的使用者驗證 中討論。

預設情況下,會為唯讀和讀寫操作建立經過驗證的 context。您應在 context-source 元素上指定要用於驗證的 LDAP 使用者的 usernamepassword

如果 username 是 LDAP 使用者的辨別名稱 (DN),則它需要是 LDAP 樹狀目錄根目錄的使用者完整 DN,無論是否在 context-source 元素上指定了 base LDAP 路徑。

某些 LDAP 伺服器設定允許匿名唯讀存取。如果您想對唯讀操作使用匿名 context,請將 anonymous-read-only 屬性設定為 true

自訂 DirContext 驗證處理

Spring LDAP 中使用的預設驗證機制是 SIMPLE 驗證。這表示 principal (由 username 屬性指定) 和憑證 (由 password 指定) 設定在傳送至 DirContext 實作建構子的 Hashtable 中。

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

您可以透過提供 DirContextAuthenticationStrategy 實作參考至 context-source 元素來指定替代的驗證機制。若要執行此操作,請設定 authentication-strategy-ref 屬性。

TLS

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

由於不同的 LDAP 伺服器實作對 TLS 通道的明確關閉 (shutdown) 有不同的回應 (某些伺服器要求優雅地關閉連線,而另一些伺服器則不支援),因此 TLS DirContextAuthenticationStrategy 實作支援透過使用 shutdownTlsGracefully 參數來指定關閉行為。如果此屬性設定為 false (預設值),則不會發生明確的 TLS 關閉。如果為 true,則 Spring LDAP 會嘗試在關閉目標 context 之前優雅地關閉 TLS 通道。

當使用 TLS 連線時,您需要確保原生 LDAP 連線池功能 (透過使用 native-pooling 屬性指定) 已關閉。如果 shutdownTlsGracefully 設定為 false,則這尤其重要。但是,由於 TLS 通道協商過程非常耗時,因此您可以透過使用 Spring LDAP 連線池支援來獲得巨大的效能優勢,這在 連線池支援 中有所描述。

自訂 Principal 和憑證管理

雖然用於建立已驗證 Context 的使用者名稱 (即使用者 DN) 和密碼預設是靜態定義的 (在 context-source 元素組態中定義的那些在 ContextSource 的整個生命週期中使用),但在某些情況下,這不是所需的行為。常見的場景是,在為該使用者執行 LDAP 操作時,應使用目前使用者的 principal 和憑證。您可以透過使用 authentication-source-ref 元素在 context-source 元素中提供對 AuthenticationSource 實作的參考,而不是明確指定 usernamepassword,來修改預設行為。每次要建立已驗證的 Context 時,ContextSource 都會查詢 AuthenticationSource 以取得 principal 和憑證。

如果您使用 Spring Security,您可以透過使用 Spring Security 隨附的 SpringSecurityAuthenticationSource 的實例組態您的 ContextSource,來確保始終使用目前登入使用者的 principal 和憑證。以下範例顯示如何執行此操作

範例 2. 使用 SpringSecurityAuthenticationSource
<beans>
...
    <ldap:context-source
        url="ldap://localhost: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 (C)、search (R)、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 的 LdapTemplate 實例,參考預設的 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 伺服器在 referral 方面存在問題。這些通常應自動追蹤。但是,如果這不起作用,它會以 PartialResultException 表現出來。將此屬性設定為 true 提供了此問題的解決方案。

odm-ref

要使用的 ObjectDirectoryMapper 實例的 ID。預設值為預設組態的 DefaultObjectDirectoryMapper

取得基礎 LDAP 路徑的參考

如先前所述,您可以為 ContextSource 提供基礎 LDAP 路徑,指定 LDAP 樹狀目錄中的根目錄,所有操作都相對於該根目錄。這表示您在整個系統中僅使用相對辨別名稱 (Distinguished Name) 工作,這通常非常方便。但是,在某些情況下,您可能需要存取基礎路徑,以便能夠建構相對於 LDAP 樹狀目錄實際根目錄的完整 DN。一個範例是在使用 LDAP 群組時 (例如,groupOfNames 物件類別)。在這種情況下,每個群組成員屬性值都需要是參考成員的完整 DN。

因此,Spring LDAP 具有一種機制,任何 Spring 控制的 bean 都可以在啟動時提供基礎路徑。為了讓 bean 收到基礎路徑的通知,需要進行兩件事。首先,想要基礎路徑參考的 bean 需要實作 BaseLdapNameAware 介面。其次,您需要在應用程式 context 中定義 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();
   }
   ...
}

以下範例顯示如何在您的 ApplicationContext 中定義 BaseLdapPathBeanPostProcessor

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

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