配置
配置 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、用户名和密码,如下所示
<ldap:context-source
username="cn=Administrator"
password="secret"
url="ldap://:389" />
上述示例创建一个具有默认值(请参阅本段后的表格)以及指定 URL 和身份验证凭据的 LdapContextSource。context-source 上可配置的属性如下(必需属性标有 *)
| 属性 | 默认值 | 描述 |
|---|---|---|
|
|
创建的 bean 的 ID。 |
|
用于与 LDAP 服务器进行身份验证的用户名(主体)。这通常是管理员用户的区分名(例如, |
|
|
用于与 LDAP 服务器进行身份验证的密码(凭据)。如果未明确配置 |
|
|
要使用的 LDAP 服务器的 URL。URL 应采用以下格式: |
|
|
|
基本 DN。配置此属性后,所有提供给 LDAP 操作和从 LDAP 操作接收的区分名都将相对于指定的 LDAP 路径。这可以显著简化针对 LDAP 树的工作。但是,在某些情况下,您需要访问基本路径。有关更多信息,请参阅获取对基本 LDAP 路径的引用 |
|
|
定义是否使用匿名(未经身份验证)上下文执行只读操作。请注意,将此参数设置为 |
|
|
定义处理引用的策略,如此处所述。有效值包括
|
|
|
指定是否应使用原生 Java LDAP 连接池。考虑改用 Spring LDAP 连接池。有关更多信息,请参阅连接池支持。 |
|
一个 |
要使用的 |
|
一个 |
要使用的 |
|
对自定义环境属性 |
DirContext 身份验证
当创建 DirContext 实例以执行 LDAP 服务器上的操作时,这些上下文通常需要进行身份验证。Spring LDAP 提供了多种配置选项来配置此功能。
本节指的是在 ContextSource 的核心功能中进行上下文身份验证,以构建 DirContext 实例供 LdapClient 和 LdapTemplate 使用。LDAP 通常仅用于用户身份验证,ContextSource 也可以用于此目的。该过程在使用 Spring LDAP 进行用户身份验证中讨论。 |
默认情况下,为只读和读写操作都创建经过身份验证的上下文。您应该在 context-source 元素上指定用于身份验证的 LDAP 用户的 username 和 password。
如果 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 代理身份验证机制或其他注意事项。
您可以通过向 context-source 元素提供 DirContextAuthenticationStrategy 实现引用来指定替代身份验证机制。为此,请设置 authentication-strategy-ref 属性。
TLS
Spring LDAP 为需要 TLS 安全通道通信的 LDAP 服务器提供了两种不同的配置选项:DefaultTlsDirContextAuthenticationStrategy 和 ExternalTlsDirContextAuthenticationStrategy。这两种实现都在目标连接上协商 TLS 通道,但它们在实际身份验证机制上有所不同。DefaultTlsDirContextAuthenticationStrategy 在安全通道上应用 SIMPLE 身份验证(使用指定的 username 和 password),而 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 实现的引用来修改默认行为,方法是使用 authentication-source-ref 元素,而不是显式指定 username 和 password。每次创建经过身份验证的 Context 时,ContextSource 都会查询 AuthenticationSource 以获取主体和凭据。
如果您使用 Spring Security,您可以通过使用 Spring Security 随附的 SpringSecurityAuthenticationSource 实例配置您的 ContextSource 来确保始终使用当前登录用户的主体和凭据。以下示例显示了如何执行此操作
<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 指定任何 username 或 password。这些属性仅在使用默认行为时才需要。 |
使用 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 连接池,以便尽快生效重置密码。 |
LdapClient 配置
LdapClient 是调用 LDAP 后端的新接口。它在以下方面改进了 LdapTemplate
-
提供内置的
Stream支持 -
提供围绕绑定 ©、搜索 ®、修改 (U)、解绑 (D) 和身份验证的简化 API。
LdapClient 尚不支持 ODM。如果您需要此功能,LdapTemplate 具有此能力。如果需要,LdapClient 和 LdapTemplate 可以在同一应用程序中很好地共存。 |
LdapClient 通过使用 LdapClient#create 工厂方法定义,如下所示
<bean id="ldapClient" class="org.springframework.ldap.core.LdapClient" factory-method="create">
<constructor-arg ref="contextSource" />
</bean>
此元素引用默认的 ContextSource,该 ContextSource 预期具有 contextSource 的 ID(context-source 元素的默认值)。
您的 LdapClient 实例可以配置为如何处理某些已检查的异常以及查询应使用哪些默认 SearchControls。
LdapTemplate 配置
LdapTemplate 通过使用 <ldap:ldap-template> 元素定义。最简单的 ldap-template 声明是元素本身
<ldap:ldap-template />
元素本身会创建一个具有默认 ID 的 LdapTemplate 实例,引用默认的 ContextSource,该 ContextSource 预期具有 contextSource 的 ID(context-source 元素的默认值)。
下表描述了 ldap-template 上可配置的属性
| 属性 | 默认值 | 描述 |
|---|---|---|
|
|
创建的 bean 的 ID。 |
|
|
要使用的 |
|
|
搜索的默认计数限制。0 表示没有限制。 |
|
|
搜索的默认时间限制,以毫秒为单位。0 表示没有限制。 |
|
|
搜索的默认搜索范围。有效值包括
|
|
|
指定在搜索中是否应忽略 |
|
|
指定在搜索中是否应忽略 |
|
要使用的 |
获取对基本 LDAP 路径的引用
如前所述,您可以向 ContextSource 提供一个基本 LDAP 路径,指定 LDAP 树中的根目录,所有操作都相对于该根目录。这意味着您在整个系统中只使用相对区分名,这通常非常方便。但是,在某些情况下,您可能需要访问基本路径,以便能够构建相对于 LDAP 树实际根目录的完整 DN。一个示例是在处理 LDAP 组时(例如,groupOfNames 对象类)。在这种情况下,每个组成员属性值都需要是引用成员的完整 DN。
因此,Spring LDAP 有一个机制,任何 Spring 控制的 bean 都可以在启动时提供基本路径。为了使 bean 收到基本路径的通知,需要满足两个条件。首先,需要基本路径引用的 bean 需要实现 BaseLdapNameAware 接口。其次,您需要在应用程序上下文中定义一个 BaseLdapPathBeanPostProcessor。以下示例显示了如何实现 BaseLdapNameAware
BaseLdapNameAwarepublic 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
<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 属性来指定要使用哪一个。