Configuration

配置 Spring LDAP 的推荐方式是使用自定义 XML 配置命名空间。为了使其可用,您需要在 bean 文件中包含 Spring LDAP 命名空间声明,如下所示:

The recommended way of configuring Spring LDAP is to use the custom XML configuration namespace. To make this available, you need to include the Spring LDAP namespace declaration in your bean file, as follows:

<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 Configuration

ContextSource 是使用 <ldap:context-source> 标记定义的。最简单的可能的 context-source 声明要求您指定服务器 URL、用户名和密码,如下所示:

ContextSource is defined by using an <ldap:context-source> tag. The simplest possible context-source declaration requires you to specify a server URL, a username, and a password, as follows:

Example 1. Simplest possible context-source declaration
<ldap:context-source
    username="cn=Administrator"
    password="secret"
    url="ldap://localhost:389" />

前一个示例创建了具有默认值(见本段之后的表格)的 LdapContextSource,以及指定的 URL 和认证凭据。context-source 上的可配置属性如下(必需属性用 * 标记):

The preceding example creates an LdapContextSource with default values (see the table after this paragraph) and the URL and authentication credentials as specified. The configurable attributes on context-source are as follows (required attributes marked with *):

Table 1. ContextSource Configuration Attributes
Attribute Default Description

id

contextSource

The ID of the created bean.

username

The username (principal) to use when authenticating with the LDAP server. This is usually the distinguished name of an admin user (for example, cn=Administrator) but may differ depending on server and authentication method. Required if authentication-source-ref is not explicitly configured.

password

The password (credentials) to use when authenticating with the LDAP server. Required if authentication-source-ref is not explicitly configured.

url *

The URL of the LDAP server to use. The URL should be in the following format: ldap://myserver.example.com:389. For SSL access, use the ldaps protocol and the appropriate port — for example, ldaps://myserver.example.com:636. If you want fail-over functionality, you can specify more than one URL, separated by commas (,).

base

LdapUtils.emptyLdapName()

The base DN. When this attribute has been configured, all Distinguished Names supplied to and received from LDAP operations are relative to the specified LDAP path. This can significantly simplify working against the LDAP tree. However, there are several occasions when you need to have access to the base path. For more information on this, see Obtaining a Reference to the Base LDAP Path

anonymous-read-only

false

Defines whether read-only operations are performed by using an anonymous (unauthenticated) context. Note that setting this parameter to true together with the compensating transaction support is not supported and is rejected.

referral

null

Defines the strategy with which to handle referrals, as described here. The valid values are:

* ignore * follow * throw

native-pooling

false

Specify whether native Java LDAP connection pooling should be used. Consider using Spring LDAP connection pooling instead. See Pooling Support for more information.

authentication-source-ref

A SimpleAuthenticationSource instance.

ID of the AuthenticationSource instance to use (see Custom Principal and Credentials Management).

authentication-strategy-ref

A SimpleDirContextAuthenticationStrategy instance.

ID of the DirContextAuthenticationStrategy instance to use (see Custom DirContext Authentication Processing).

base-env-props-ref

A reference to a Map of custom environment properties that should supplied with the environment sent to the DirContext on construction.

DirContext Authentication

当创建 DirContext 实例以用于执行 LDAP 服务器上的操作时,这些上下文通常需要被认证。Spring LDAP 提供了多个选项来配置它。

When DirContext instances are created to be used for performing operations on an LDAP server, these contexts often need to be authenticated. Spring LDAP offers various options for configuring this.

此部分是指 ContextSource 的核心功能中的身份验证上下文,以构造 DirContext 实例以供 LdapClientLdapTemplate 使用。LDAP 通常仅用于用户身份验证,ContextSource 也可用于此目的。该过程在 User Authentication using Spring LDAP 中讨论。

This section refers to authenticating contexts in the core functionality of the ContextSource, to construct DirContext instances for use by LdapClient and LdapTemplate. LDAP is commonly used for the sole purpose of user authentication, and the ContextSource may be used for that as well. That process is discussed in User Authentication using Spring LDAP.

默认情况下,为只读和读写操作创建已认证上下文。您应该在 context-source 元素上指定要用于认证的 LDAP 用户的 usernamepassword

By default, authenticated contexts are created for both read-only and read-write operations. You should specify the username and password of the LDAP user to be used for authentication on the context-source element.

如果 username 是 LDAP 用户的识别名称 (DN),则它必须是从 LDAP 树根起的用户的完整 DN,无论是否在 context-source 元素上指定了 base LDAP 路径。

If username is the Distinguished Name (DN) of an LDAP user, it needs to be the full DN of the user from the root of the LDAP tree, regardless of whether a base LDAP path has been specified on the context-source element.

有些 LDAP 服务器设置允许匿名只读访问。如果您想针对只读操作使用匿名上下文,请将 anonymous-read-only 属性设置为 true

Some LDAP server setups allow anonymous read-only access. If you want to use anonymous contexts for read-only operations, set the anonymous-read-only attribute to true.

Custom DirContext Authentication Processing

Spring LDAP 中使用的默认认证机制是 SIMPLE 认证。这意味着主体(如 username 属性所指定)和凭据(如 password 所指定)将在发送到 DirContext 实现构造函数的 Hashtable 中设置。

The default authentication mechanism used in Spring LDAP is SIMPLE authentication. This means that the principal (as specified by the username attribute) and the credentials (as specified by the password) are set in the Hashtable that is sent to the DirContext implementation constructor.

很多情况下,这个处理过程是不够的。例如,LDAP 服务器通常被设置为仅接受安全 TLS 通道上的通信。可能有必要使用特定的 LDAP 代理认证机制或其他关注点。

There are many occasions when this processing is not sufficient. For instance, LDAP Servers are commonly set up to accept communication only on a secure TLS channel. There might be a need to use the particular LDAP Proxy Auth mechanism or other concerns.

您可以通过向 context-source 元素提供 DirContextAuthenticationStrategy 实现引用来指定其他认证机制。若要这样做,请设置 authentication-strategy-ref 属性。

You can specify an alternative authentication mechanism by supplying a DirContextAuthenticationStrategy implementation reference to the context-source element. To do so, set the authentication-strategy-ref attribute.

TLS

Spring LDAP 提供了针对要求 TLS 安全通道通信的 LDAP 服务器的两个不同的配置选项:DefaultTlsDirContextAuthenticationStrategyExternalTlsDirContextAuthenticationStrategy.这两个实现的协商目标连接上的 TLS 通道,但是它们在实际认证机制中不同。DefaultTlsDirContextAuthenticationStrategy 在安全通道上(通过使用指定的 usernamepassword)应用 SIMPLE 认证,而 ExternalTlsDirContextAuthenticationStrategy 使用外部 SASL 认证,应用由使用系统属性配置的客户端证书进行认证。

Spring LDAP provides two different configuration options for LDAP servers that require TLS secure channel communication: DefaultTlsDirContextAuthenticationStrategy and ExternalTlsDirContextAuthenticationStrategy. Both implementations negotiate a TLS channel on the target connection, but they differ in the actual authentication mechanism. Where DefaultTlsDirContextAuthenticationStrategy applies SIMPLE authentication on the secure channel (by using the specified username and password), the ExternalTlsDirContextAuthenticationStrategy uses EXTERNAL SASL authentication, applying a client certificate that is configured by using system properties for authentication.

由于不同的 LDAP 服务器实现对 TLS 通道的显式关闭的响应不同(有些服务器需要平滑关闭连接,而其他服务器不支持),TLS DirContextAuthenticationStrategy 实现支持使用 shutdownTlsGracefully 参数指定关闭行为。如果这个属性被设置为 false(默认值),则不会发生显式 TLS 关闭。如果它是 true,Spring LDAP 会尝试在关闭目标上下文之前平滑关闭 TLS 通道。

Since different LDAP server implementations respond differently to explicit shutdown of the TLS channel (some servers require the connection be shut down gracefully, while others do not support it), the TLS DirContextAuthenticationStrategy implementations support specifying the shutdown behavior by using the shutdownTlsGracefully parameter. If this property is set to false (the default), no explicit TLS shutdown happens. If it is true, Spring LDAP tries to shut down the TLS channel gracefully before closing the target context.

使用 TLS 连接时,您需要确保原生 LDAP 池化功能(如使用 native-pooling 属性指定的那样)已关闭。如果将 shutdownTlsGracefully 设置为 false,这一点尤为重要。然而,由于 TLS 通道协商过程相当昂贵,您可以通过使用 Pooling Support 中描述的 Spring LDAP 池化支持获得极大的性能提升。

When working with TLS connections, you need to make sure that the native LDAP Pooling functionality (as specified by using the native-pooling attribute) is turned off. This is particularly important if shutdownTlsGracefully is set to false. However, since the TLS channel negotiation process is quite expensive, you can gain great performance benefits by using the Spring LDAP Pooling Support, described in Pooling Support.

Custom Principal and Credentials Management

虽然用于创建已认证 Context 的用户名(即用户 DN)和密码默认情况下被静态定义(context-source 元素配置中定义的那些在 ContextSource 的整个生命周期中使用),但在某些情况下这不是所需的行为。一种常见情况是,在为该用户执行 LDAP 操作时,应该使用当前用户的身份主体和凭据。您可以通过向 context-source 元素提供 AuthenticationSource 实现的引用(使用 authentication-source-ref 元素),而不是显式指定 usernamepassword 来修改默认行为。每次要创建一个认证的 Context 时,ContextSource 都会查询 AuthenticationSource 身份主体和凭据。

While the user name (that is, the user DN) and password used for creating an authenticated Context are statically defined by default (the ones defined in the context-source element configuration are used throughout the lifetime of the ContextSource), there are several cases where this is not the desired behavior. A common scenario is that the principal and credentials of the current user should be used when performing LDAP operations for that user. You can modify the default behavior by supplying a reference to an AuthenticationSource implementation to the context-source element by using the authentication-source-ref element, instead of explicitly specifying the username and password. The AuthenticationSource is queried by the ContextSource for principal and credentials each time an authenticated Context is to be created.

如果你使用 Spring Security,可以通过使用 Spring Security 附带的 SpringSecurityAuthenticationSource 实例配置 ContextSource 来确保始终使用当前登录用户的负责人和凭证。以下示例展示了如何操作:

If you use Spring Security, you can make sure the principal and credentials of the currently logged-in user are used at all times by configuring your ContextSource with an instance of the SpringSecurityAuthenticationSource shipped with Spring Security. The following example shows how to do so:

Example 2. Using the 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 时,我们未为 usernamepassword 指定任何。当使用默认行为时才需要这些属性。

We do not specify any username or password for. our context-source when using an AuthenticationSource. These properties are needed only when the default behavior is used.

使用 SpringSecurityAuthenticationSource 时,您需要使用 Spring Security 的 LdapAuthenticationProvider 对用户进行 LDAP 认证。

When using the SpringSecurityAuthenticationSource, you need to use Spring Security’s LdapAuthenticationProvider to authenticate the users against LDAP.

Native Java LDAP Pooling

内部 Java LDAP 提供程序提供一些非常基本的连接池功能。你可以在 AbstractContextSource 中使用 pooled 标志来启用或禁用此 LDAP 连接池。默认值为 false(自版本 1.3 起)——即,Java 原生 LDAP 连接池已关闭。LDAP 连接池的配置通过使用 System 属性进行管理,因此你需要在 Spring 上下文配置外部手动处理此操作。你可以在 here 中找到本机连接池配置的详细信息。

The internal Java LDAP provider provides some very basic pooling capabilities. You can turn this LDAP connection pooling on or off by using the pooled flag on AbstractContextSource. The default value is false (since release 1.3) — that is, the native Java LDAP pooling is turned off. The configuration of LDAP connection pooling is managed by using System properties, so you need to handle this manually, outside of the Spring Context configuration. You can find details of the native pooling configuration here.

原生 LDAP 连接池化存在几个严重的缺陷,这就是 Spring LDAP 提供一种更为复杂的方法进行 LDAP 连接池化的原因,如 Pooling Support 中所述。如果您需要池化功能,这是推荐的做法。

There are several serious deficiencies in the built-in LDAP connection pooling, which is why Spring LDAP provides a more sophisticated approach to LDAP connection pooling, described in Pooling Support. If you need pooling functionality, this is the recommended approach.

无论池配置如何,ContextSource#getContext(String principal, String credentials) 方法始终明确不使用本机 Java LDAP 池,以便密码重置尽快生效。

Regardless of the pooling configuration, the ContextSource#getContext(String principal, String credentials) method always explicitly does not use native Java LDAP Pooling, in order for reset passwords to take effect as soon as possible.

Advanced ContextSource Configuration

本节涵盖了更高级的 ContextSource 配置方式。

This section covers more advanced ways to configure a ContextSource.

Custom DirContext Environment Properties

在某些情况下,除了直接在 context-source 中可配置的属性以外,您可能还想指定其他环境设置属性。您应该将此类属性设置在 Map 中,并在 base-env-props-ref 属性中引用它们。

In some cases, you might want to specify additional environment setup properties, in addition to the ones directly configurable on context-source. You should set such properties in a Map and reference them in the base-env-props-ref attribute.

LdapClient Configuration

LdapClient 是用于调用 LDAP 后端的全新接口。它通过以下方式改进了 LdapTemplate

LdapClient is the new interface for calling an LDAP backend. It improves upon LdapTemplate in the following ways:

  • Provides built-in Stream support

  • Provides a simplified API centered around bind ©, search ®, modify (U), unbind (D), and authenticate.

LdapClient 还不支持 ODM。如果您需要,LdapTemplate 具备此功能。如果需要,LdapClientLdapTemplate 能在同一应用程序中很好地共存。

LdapClient does not yet support ODM. If this is something you need, LdapTemplate has this capacity. Both LdapClient and LdapTemplate can coexist quite nicely in the same application, if needed.

使用 LdapClient#create 工厂方法可以定义一个 LdapClient,如下所示:

An LdapClient is defined by using the LdapClient#create factory method like so:

Example 3. Simplest possible LdapClient declaration
<bean id="ldapClient" class="org.springframework.ldap.core.LdapClient" factory-method="create">
   <constructor-arg ref="contextSource" />
</bean>

此元素引用默认的 ContextSource,预计其 ID 为 contextSourcecontext-source 元素的默认值)。

This element references the default ContextSource, which is expected to have an ID of contextSource (the default for the context-source element).

您的 LdapClient 实例可以配置为如何处理某些已检查异常以及查询应该使用哪些默认 SearchControls

Your LdapClient instance can be configured for how to handle certain checked exceptions and what any default SearchControls should be used for queries.

LdapTemplate Configuration

LdapTemplate 通过使用 <ldap:ldap-template> 元素定义。最简单的可能的 ldap-template 声明是元素本身:

The LdapTemplate is defined by using a <ldap:ldap-template> element. The simplest possible ldap-template declaration is the element by itself:

Example 4. Simplest possible ldap-template declaration
<ldap:ldap-template />

元素本身会创建一个 LdapTemplate 实例(ID 为默认值),引用默认的 ContextSource,预计其 ID 为 contextSourcecontext-source 元素的默认值)。

The element by itself creates an LdapTemplate instance with the default ID, referencing the default ContextSource, which is expected to have an ID of contextSource (the default for the context-source element).

下表描述了 ldap-template 中的可配置属性:

The following table describes the configurable attributes on ldap-template:

Table 2. LdapTemplate Configuration Attributes
Attribute Default Description

id

ldapTemplate

The ID of the created bean.

context-source-ref

contextSource

The ID of the ContextSource instance to use.

count-limit

0

The default count limit for searches. 0 means no limit.

time-limit

0

The default time limit for searches, in milliseconds. 0 means no limit.

search-scope

SUBTREE

The default search scope for searches. The valid values are:

  • OBJECT

  • ONELEVEL

  • SUBTREE

ignore-name-not-found

false

Specifies whether a NameNotFoundException should be ignored in searches. Setting this attribute to true make errors that are caused by an invalid search base be silently swallowed.

ignore-partial-result

false

Specifies whether PartialResultException should be ignored in searches. Some LDAP servers have problems with referrals. These should normally be followed automatically. However, if this does not work, it manifests itself with a PartialResultException. Setting this attribute to true presents a work-around to this problem.

odm-ref

The ID of the ObjectDirectoryMapper instance to use. The default is a default-configured DefaultObjectDirectoryMapper.

Obtaining a Reference to the Base LDAP Path

如前所述,您可以为 ContextSource 提供基础 LDAP 路径,指定所有操作相对的 LDAP 树根。这意味着您仅会在整个系统中使用相对可分辨名称,这通常非常方便。但是,在某些情况下,您可能需要访问基础路径才能构建相对于 LDAP 树实际根的全 DN。一个示例将在使用 LDAP 组(例如 groupOfNames 对象类)时遇到。在这种情况下,每个组成员属性值都需要是引用成员的全 DN。

As described earlier, you can supply a base LDAP path to the ContextSource, specifying the root in the LDAP tree to which all operations are relative. This means that you are working only with relative distinguished names throughout your system, which is typically rather handy. There are, however, some cases in which you may need to have access to the base path in order to be able to construct full DNs, relative to the actual root of the LDAP tree. One example would be when working with LDAP groups (for example, the groupOfNames object class). In that case, each group member attribute value needs to be the full DN of the referenced member.

正因为如此,Spring LDAP 有一种机制,通过该机制,任何受 Spring 控制的 Bean 都可以在启动时提供基础路径。为了让 Bean 被基础路径通知,需要实现两件事。首先,想要获取基础路径引用的 Bean 需要实现 BaseLdapNameAware 接口。其次,您需要在应用程序上下文中定义 BaseLdapPathBeanPostProcessor。以下示例演示了如何实现 BaseLdapNameAware

For that reason, Spring LDAP has a mechanism by which any Spring-controlled bean may be supplied with the base path on startup. For beans to be notified of the base path, two things need to be in place. First, the bean that wants the base path reference needs to implement the BaseLdapNameAware interface. Second, you need to define a BaseLdapPathBeanPostProcessor in the application context. The following example shows how to implement BaseLdapNameAware:

Example 5. Implementing 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

The following example shows how to define a BaseLdapPathBeanPostProcessor:

Example 6. Specifying a BaseLdapPathBeanPostProcessor in your ApplicationContext
<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 属性来指定要使用哪一个。

The default behavior of the BaseLdapPathBeanPostProcessor is to use the base path of the single defined BaseLdapPathSource (AbstractContextSource) in the ApplicationContext. If more than one BaseLdapPathSource is defined, you need to specify which one to use by setting the baseLdapPathSourceName property.