Configuration
配置 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 Configuration
ContextSource 是使用 <ldap:context-source> 标记定义的。最简单的可能的 context-source 声明要求您指定服务器 URL、用户名和密码,如下所示:
<ldap:context-source
username="cn=Administrator"
password="secret"
url="ldap://localhost:389" />
前一个示例创建了具有默认值(见本段之后的表格)的 LdapContextSource,以及指定的 URL 和认证凭据。context-source 上的可配置属性如下(必需属性用 * 标记):
| Attribute | Default | Description |
|---|---|---|
|
|
已创建 bean 的 ID。 |
|
使用 LDAP 服务器进行身份验证时要使用的用户名(主体)。通常是管理员用户的识别名称(例如 |
|
|
使用 LDAP 服务器进行身份验证时要使用的密码(凭据)。如果未明确配置 |
|
|
要使用的 LDAP 服务器的 URL。URL 应采用以下格式: |
|
|
|
基本 DN。配置此属性后,提供给 LDAP 操作和从 LDAP 操作接收的所有识别名称都将与此 LDAP 路径相关。这会极大地简化针对 LDAP 树的工作。但是,有几种情况需要访问基本路径。有关详细信息,请参阅 Obtaining a Reference to the Base LDAP Path |
|
|
定义是否通过匿名(未经身份验证)上下文执行只读操作。请注意,将此参数设置为 |
|
|
定义处理转介的策略,如 here所述。有效值为:* |
|
|
指定是否应使用本机 Java LDAP 连接池。考虑改为使用 Spring LDAP 连接池。如需了解更多信息,请参阅 Pooling Support。 |
|
A |
要使用的 `AuthenticationSource`实例的 ID(参见 Custom Principal and Credentials Management)。 |
|
A |
要使用的 |
|
要随环境一起提供给在构建时发送到 |
DirContext Authentication
当创建 DirContext 实例以用于执行 LDAP 服务器上的操作时,这些上下文通常需要被认证。Spring LDAP 提供了多个选项来配置它。
|
此部分是指 |
默认情况下,为只读和读写操作创建已认证上下文。您应该在 context-source 元素上指定要用于认证的 LDAP 用户的 username 和 password。
|
如果 |
有些 LDAP 服务器设置允许匿名只读访问。如果您想针对只读操作使用匿名上下文,请将 anonymous-read-only 属性设置为 true。
Custom DirContext Authentication Processing
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 在安全通道上(通过使用指定的 username 和 password)应用 SIMPLE 认证,而 ExternalTlsDirContextAuthenticationStrategy 使用外部 SASL 认证,应用由使用系统属性配置的客户端证书进行认证。
由于不同的 LDAP 服务器实现对 TLS 通道的显式关闭的响应不同(有些服务器需要平滑关闭连接,而其他服务器不支持),TLS DirContextAuthenticationStrategy 实现支持使用 shutdownTlsGracefully 参数指定关闭行为。如果这个属性被设置为 false(默认值),则不会发生显式 TLS 关闭。如果它是 true,Spring LDAP 会尝试在关闭目标上下文之前平滑关闭 TLS 通道。
|
使用 TLS 连接时,您需要确保原生 LDAP 池化功能(如使用 |
Custom Principal and Credentials Management
虽然用于创建已认证 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://localhost:389"
authentication-source-ref="springSecurityAuthenticationSource"/>
<bean id="springSecurityAuthenticationSource"
class="org.springframework.security.ldap.authentication.SpringSecurityAuthenticationSource" />
...
</beans>
|
在我们使用 |
|
使用 |
Native Java LDAP Pooling
内部 Java LDAP 提供程序提供一些非常基本的连接池功能。你可以在 AbstractContextSource 中使用 pooled 标志来启用或禁用此 LDAP 连接池。默认值为 false(自版本 1.3 起)——即,Java 原生 LDAP 连接池已关闭。LDAP 连接池的配置通过使用 System 属性进行管理,因此你需要在 Spring 上下文配置外部手动处理此操作。你可以在 here 中找到本机连接池配置的详细信息。
|
原生 LDAP 连接池化存在几个严重的缺陷,这就是 Spring LDAP 提供一种更为复杂的方法进行 LDAP 连接池化的原因,如 Pooling Support 中所述。如果您需要池化功能,这是推荐的做法。 |
|
无论池配置如何, |
LdapClient Configuration
LdapClient 是用于调用 LDAP 后端的全新接口。它通过以下方式改进了 LdapTemplate:
-
Provides built-in
Streamsupport -
提供了一个简化的 API,其中重点关注绑定 ©、搜索 ®、修改 (U)、解除绑定 (D) 和身份验证。
|
|
使用 LdapClient#create 工厂方法可以定义一个 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 Configuration
LdapTemplate 通过使用 <ldap:ldap-template> 元素定义。最简单的可能的 ldap-template 声明是元素本身:
<ldap:ldap-template />
元素本身会创建一个 LdapTemplate 实例(ID 为默认值),引用默认的 ContextSource,预计其 ID 为 contextSource(context-source 元素的默认值)。
下表描述了 ldap-template 中的可配置属性:
| Attribute | Default | Description |
|---|---|---|
|
|
已创建 bean 的 ID。 |
|
|
要使用的 |
|
|
搜索的默认计数限制。0 表示无限制。 |
|
|
搜索的默认时间限制(以毫秒为单位)。0 表示无限制。 |
|
|
搜索的默认搜索范围。有效值为:* |
|
|
指定是否应在搜索中忽略 |
|
|
指定是否应在搜索中忽略 |
|
要使用的 |
Obtaining a Reference to the Base LDAP Path
如前所述,您可以为 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://localhost:389"
base="dc=261consulting,dc=com" />
...
*<bean class="org.springframework.ldap.core.support.BaseLdapPathBeanPostProcessor" />*
</beans>
BaseLdapPathBeanPostProcessor 的默认行为是使用 ApplicationContext 中单个已定义 BaseLdapPathSource (AbstractContextSource) 的基础路径。如果定义了多个 BaseLdapPathSource,您需要通过设置 baseLdapPathSourceName 属性来指定要使用哪一个。