配置
配置 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 操作接收的所有判别名 (Distinguished Names) 都相对于指定的 LDAP 路径。这可以显著简化对 LDAP 树的操作。但是,在某些情况下,您可能需要访问基准路径,以便构建相对于 LDAP 树实际根的完整 DN。一个例子是处理 LDAP 组(例如 |
|
|
定义是否使用匿名(未认证)上下文执行只读操作。请注意,将此参数设置为 |
|
|
定义处理 referrals 的策略,如 这里 所述。有效值包括
|
|
|
指定是否应使用原生的 Java LDAP 连接池。建议改用 Spring LDAP 连接池。更多信息请参见 连接池支持。 |
|
一个 |
要使用的 |
|
一个 |
要使用的 |
|
对一个 |
DirContext 认证
创建用于在 LDAP 服务器上执行操作的 DirContext 实例时,这些上下文通常需要经过认证。Spring LDAP 提供了各种配置选项。
本节涉及在 ContextSource 的核心功能中认证上下文,以构建供 LdapClient 和 LdapTemplate 使用的 DirContext 实例。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 Proxy Auth 机制或其他考虑事项。
您可以通过向 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 实现引用,而不是显式指定 username 和 password,来修改默认行为。ContextSource 会在每次需要创建已认证 Context 时查询 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支持 -
提供一个围绕 bind ©、search ®、modify (U)、unbind (D) 和 authenticate 的简化 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,预期其 ID 为 contextSource(即 context-source 元素的默认值)。
您可以配置 LdapClient 实例如何处理某些已检查异常以及任何默认的 SearchControls 应如何用于查询。
LdapTemplate 配置
LdapTemplate 通过使用 <ldap:ldap-template> 元素定义。最简单的 ldap-template 声明就是元素本身
<ldap:ldap-template />
元素本身会创建一个 ID 为默认值、引用默认 ContextSource 的 LdapTemplate 实例,该 ContextSource 的 ID 预期为 contextSource(即 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
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
<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 属性来指定使用哪一个。