配置
配置 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://127.0.0.1:389" />
上面的示例创建了一个 LdapContextSource
,它具有默认值(请参阅本段后的表格)以及指定的 URL 和身份验证凭据。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 核心功能中对上下文进行身份验证,以构建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代理身份验证机制或其他问题。
您可以通过向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://127.0.0.1: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 上下文配置之外手动处理它。您可以在 此处 找到原生池化配置的详细信息。
内置 LDAP 连接池化存在一些严重的缺陷,这就是 Spring LDAP 提供更复杂的方法来进行 LDAP 连接池化的原因,如 池化支持 中所述。如果您需要池化功能,这是推荐的方法。 |
无论池化配置如何,ContextSource#getContext(String principal, String credentials) 方法始终明确地不使用原生 Java LDAP 池化,以便重置密码尽快生效。
|
LdapClient
配置
LdapClient
是用于调用 LDAP 后端的新的接口。它在以下方面改进了 LdapTemplate
-
提供内置
Stream
支持 -
提供一个简化的 API,围绕绑定 ©、搜索 ®、修改 (U)、解绑 (D) 和身份验证。
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
预计具有 ID contextSource
(context-source
元素的默认值)。
您可以为 LdapClient
实例配置如何处理某些已检查异常以及应使用哪些默认 SearchControls
进行查询。
LdapTemplate
配置
LdapTemplate
通过使用 <ldap:ldap-template>
元素定义。最简单的 ldap-template
声明是元素本身
<ldap:ldap-template />
元素本身创建了一个具有默认 ID 的 LdapTemplate
实例,引用默认的 ContextSource
,该 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
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://127.0.0.1:389"
base="dc=261consulting,dc=com" />
...
<bean class="org.springframework.ldap.core.support.BaseLdapPathBeanPostProcessor" />
</beans>
BaseLdapPathBeanPostProcessor
的默认行为是使用 ApplicationContext
中定义的单个 BaseLdapPathSource
(AbstractContextSource
)的基本路径。如果定义了多个 BaseLdapPathSource
,则需要通过设置 baseLdapPathSourceName
属性来指定要使用哪个 BaseLdapPathSource
。