配置
配置 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://localhost: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://localhost: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://localhost:389"
base="dc=261consulting,dc=com" />
...
<bean class="org.springframework.ldap.core.support.BaseLdapPathBeanPostProcessor" />
</beans>
BaseLdapPathBeanPostProcessor
的默认行为是使用 ApplicationContext
中单个定义的 BaseLdapPathSource
(AbstractContextSource
) 的基准路径。如果定义了多个 BaseLdapPathSource
,则需要通过设置 baseLdapPathSourceName
属性来指定使用哪一个。