配置
推荐的配置 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" />
前面的示例创建了一个具有默认值的 LdapContextSource(请参阅此段落后面的表格),并指定了 URL 和身份验证凭据。 context-source 上可配置的属性如下(必填属性用 * 标记):
| 属性 | 默认 | 描述 |
|---|---|---|
|
|
创建的bean的ID。 |
|
用于与LDAP服务器进行身份验证的用户名(主体)。这通常是管理员用户的区分名称(例如, |
|
|
用于在与LDAP服务器进行身份验证时使用的密码(凭据)。如果未显式配置 |
|
|
要使用的LDAP服务器的URL。URL应以以下格式提供: |
|
|
|
基本DN。当此属性已配置时,所有传递给和从LDAP操作接收的区分名称都将相对于指定的LDAP路径。 这可以显著简化对LDAP树的工作。但是,在某些情况下,你需要访问基础路径。 更多信息,请参见 获取基础LDAP路径的引用 |
|
|
定义是否通过匿名(未认证)事务上下文执行只读操作。
注意:将此参数设置为 |
|
|
定义处理引用的策略,如在此处所述。有效的值为:
|
|
|
指定是否应使用原生的Java LDAP连接池。考虑使用Spring LDAP连接池。有关更多信息,请参见连接池支持。 |
|
一个 |
用于 |
|
一个 |
要使用的 |
|
一个指向应随构造时发送到 |
DirContext身份验证
当 DirContext 个实例被创建用于在 LDAP 服务器上执行操作时,这些上下文 通常 需要进行认证。
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 用户认证使用Spring LDAP. |
默认情况下,对于只读和读写操作都会创建经过身份验证的上下文。你应该在context-source元素中指定用于身份验证的LDAP用户的username和password。
如果 LDAP 用户的区分名称(DN)为 username,则必须是从 LDAP 树根开始的该用户的完整 DN,无论在 context-source 元素上的 base LDAP 路径是否已指定。 |
一些LDAP服务器配置允许匿名只读访问。如果你想使用匿名上下文进行只读操作,将anonymous-read-only属性设置为true。
自定义DirContext认证处理
Spring LDAP 默认使用的认证机制是 SIMPLE 认证。这意味着,principal(由 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连接池支持来获得显著的性能提升,该支持在连接池支持中描述。 |
自定义 Principal 和凭证管理
当使用创建经过身份验证的Context的用户名称(即用户DN)和密码时,默认情况下是静态定义的(使用在context-source元素配置中定义的值,贯穿ContextSource的整个生命周期)。在一些情况下,这种默认行为并不是用户所期望的。一个常见的场景是,在为该用户执行LDAP操作时,应使用当前用户的主体(principal)和凭据。可以通过在context-source元素中使用authentication-source-ref元素提供一个AuthenticationSource实现的引用,而不是显式地指定username和password。每次需要创建经过身份验证的Context时,ContextSource都会查询AuthenticationSource以获取主体和凭据。
如果你使用 Spring Security,你就可以通过将你的 ContextSource 配置为包含随 Spring Security 一起提供的 SpringSecurityAuthenticationSource 的实例,确保在所有时刻都使用当前登录用户的主体(principal)和凭据(credentials)。以下示例展示了如何进行配置:
<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://example.com:389\" 的认证。 |
原生 Java LDAP 缓存池
内部的 Java LDAP 提供程序提供了一些非常基础的连接池功能。您可以使用 pooled 标志来开启或关闭 AbstractContextSource。从 1.3 版本起,默认值为 false —— 也就是说,原生的 Java LDAP 连接池功能是关闭的。LDAP 连接池的配置由使用 System 属性进行管理,因此需要手动处理,而不能在 Spring 上下文配置中设置。有关原生池配置的详细信息,请参见 此处。
| 内置LDAP连接池存在几个严重的缺陷,因此Spring LDAP提供了一种更高级的LDAP连接池方法,详情请参阅Pooling Support。如果您需要连接池功能,这是推荐的方法。 |
无论池化配置如何,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配置
0 由使用一个 1 元素来定义。最简单的 2 声明就是该元素本身:
<ldap:ldap-template />
该元素本身会创建一个具有默认ID的LdapTemplate实例,引用默认的ContextSource,该ContextSource预期具有ID为contextSource(context-source元素的默认值)。
以下表格描述了在ldap-template上的可配置属性:
| 属性 | 默认 | 描述 |
|---|---|---|
|
|
创建的bean的ID。 |
|
|
用于使用的 |
|
|
默认搜索数量限制。0 表示无限。 |
|
|
默认搜索时间限制,以毫秒为单位。0 表示无限制。 |
|
|
默认的搜索范围用于搜索。默认的值为:
|
|
|
指定在搜索中是否忽略 |
|
|
指定在搜索中是否忽略 |
|
要使用的 |
获取基础LDAP路径的引用
正如前面所述,你可以将一个基础LDAP路径提供给ContextSource,指定所有操作相对于的LDAP树的根。这意味着你将在整个系统中只使用相对区分名称,这通常很方便。然而,在某些情况下,你可能需要访问基础路径,以便能够相对于LDAP树的实际根构造完整的DN。一个例子是在处理LDAP组(例如,groupOfNames对象类)时。在这种情况下,每个组成员属性值需要是所引用成员的完整DN。
为此原因,Spring LDAP 提供了一种机制,使得任何由 Spring 控制的 bean 在启动时都可以获得基础路径。
为了让 beans 获得基础路径通知,需要满足两件事情。首先,想要获得基础路径引用的 bean 需要实现 LdapBasePathConfigurer 接口。
其次,你需要在应用程序上下文中定义一个 BasePathBeanConfigurer。
以下示例展示了如何实现 BasePathConfigurerImpl:
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 会使用单个定义的 BaseLdapPathSource(AbstractContextSource)在 ApplicationContext 中的基路径。如果定义了多个 BaseLdapPathSource,需要通过设置 baseLdapPathSourceName 属性来指定使用哪一个。