Introduction

Overview

Spring LDAP 旨在简化 Java 中的 LDAP 编程。该库提供的一些功能包括:

  • JdbcTemplate样式模板对 LDAP 编程的简化。

  • 基于 JPA 或 Hibernate 样式注释的对象和目录映射。

  • Spring Data 存储库支持,包括对 QueryDSL 的支持。

  • 简化 LDAP 查询和识别名的构建的实用程序。

  • Proper LDAP connection pooling.

  • 客户端 LDAP 补偿事务支持。

Traditional Java LDAP versus LdapClient

考虑一种方法,该方法应针对存储中的所有人员进行搜索,并在列表中返回其姓名。通过使用 JDBC,我们将创建一个 连接,并使用 语句 运行一个 查询。然后我们将遍历 结果集 并检索所需的 ,将其添加到列表中。

通过使用 JNDI 针对一个 LDAP 数据库工作,我们将创建一个 上下文,并使用 搜索过滤器 执行一个 搜索。然后我们将遍历由此产生的 命名枚举,检索所需的 属性,并将它添加到列表中。

使用 Java LDAP 实现人员姓名搜索方法的传统方法如下例所示。注意用*加粗*标记的代码 - 这是执行与方法业务目的相关任务的实际代码。其余部分是管道。

public class TraditionalPersonRepoImpl implements PersonRepo {
   public List<String> getAllPersonNames() {
      Hashtable env = new Hashtable();
      env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
      env.put(Context.PROVIDER_URL, "ldap://localhost:389/dc=example,dc=com");

      DirContext ctx;
      try {
         ctx = new InitialDirContext(env);
      } catch (NamingException e) {
         throw new RuntimeException(e);
      }

      List<String> list = new LinkedList<String>();
      NamingEnumeration results = null;
      try {
         SearchControls controls = new SearchControls();
         controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
         results = ctx.*search*("", *"(objectclass=person)"*, controls);

         while (results.hasMore()) {
            SearchResult searchResult = (SearchResult) results.next();
            Attributes attributes = searchResult.getAttributes();
            *Attribute attr = attributes.get("cn");
            String cn = attr.get().toString();*
            list.add(cn);
         }
      } catch (NameNotFoundException e) {
         // The base context was not found.
         // Just clean up and exit.
      } catch (NamingException e) {
         throw new RuntimeException(e);
      } finally {
         if (results != null) {
            try {
               results.close();
            } catch (Exception e) {
               // Never mind this.
            }
         }
         if (ctx != null) {
            try {
               ctx.close();
            } catch (Exception e) {
               // Never mind this.
            }
         }
      }
      *return list;*
   }
}

通过使用 Spring LDAP AttributesMapperLdapClient 类,我们使用以下代码获得了完全相同的功能:

import static org.springframework.ldap.query.LdapQueryBuilder.query;

public class PersonRepoImpl implements PersonRepo {
   private LdapClient ldapClient;

   public void setLdapClient(LdapClient ldapClient) {
      this.ldapClient = ldapClient;
   }

   public List<String> getAllPersonNames() {
      return ldapClient.search().query(
            *query().where("objectclass").is("person")*
         ).toObject((Attributes attrs) ->
            *attrs.get("cn").get().toString();*
         );
   }
}

样板代码的数量明显少于传统示例。LdapClient 的搜索方法确保创建了一个 DirContext 实例,执行了搜索,使用给定的 AttributesMapper 将属性映射到一个字符串,将字符串收集到一个内部列表中,最后返回列表。它还确保正确关闭了 NamingEnumerationDirContext,并处理可能发生的任何异常。

当然,由于这是一个 Spring 框架子项目,因此我们使用 Spring 来配置我们的应用程序,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<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">

   <ldap:context-source
          url="ldap://localhost:389"
          base="dc=example,dc=com"
          username="cn=Manager"
          password="secret" />

   <bean id="ldapClient" class="org.springframework.ldap.core.LdapClient" factory-method="create">
        <constructor-arg ref="contextSource" />
    </bean>

   <bean id="personRepo" class="com.example.repo.PersonRepoImpl">
      <property name="ldapClient" ref="ldapClient" />
   </bean>
</beans>

要使用自定义 XML 名称空间来配置 Spring LDAP 组件,您需要在 XML 声明中包含这些名称空间的引用,如前面的示例所示。

What’s new in 2.2

有关 2.2 的完整详细信息,请参阅以下变更日志:@17"。Spring LDAP 2.2 的亮点如下:

  • #415:增加了对 Spring 5 的支持

  • #399:嵌入式 UnboundID LDAP 服务器支持

  • #410:增加了用于 Commons Pool 2 支持的文档

What’s new in 2.1

有关 2.1 的完整详细信息,请参阅以下变更日志:@18" 和 @"19"。Spring LDAP 2.1 的亮点如下。

  • #390:增加了 Spring Data Hopper 支持

  • #351:增加了对 commons-pool2 的支持

  • #370:在 XML 命名空间中增加了支持属性占位符

  • #392:增加了文档测试支持

  • #401:增加了一个断言的切换

  • 从 JIRA 迁移到 GitHub Issues

  • Added Gitter Chat

What’s new in 2.0

尽管 Spring LDAP API 在 2.0 版本中进行了相当重要的现代化改造,但已非常小心地确保了向后兼容性,尽可能做到。使用 Spring LDAP 1.3.x 的代码应该在无任何修改的情况下与 2.0 库一起编译并运行,只有少数例外。

例外是一些类,它们已移动到新包以便让几个重要的重构成为可能。移动的类通常不是预期公共 API 的一部分,而迁移过程应该很平稳。每当在升级后找不到某个 Spring LDAP 类时,都应该组织 IDE 中的导入。

不过,您应该会遇到一些弃用警告,还有许多其他 API 改进。有关充分利用 2.0 的建议是:放弃使用已弃用的类和方法,并迁移到新的改进版 API 实用程序。

以下列表简要描述了 Spring LDAP 2.0 中最重要的变更:

  • Java 6 现在是 Spring LDAP 所必需的。2.0 及其之后的 Spring 版本仍然支持。

  • 中心 API 已使用 Java 5+ 功能(例如泛型和变长参数)进行更新。因此,整个 spring-ldap-tiger 模块已弃用,我们建议您迁移到使用 Spring LDAP 的核心类。核心接口的参数化导致现有代码中产生大量编译警告,我们建议您采取适当的措施消除这些警告。

  • ODM(对象目录映射)功能已移至核心,且 LdapOperationsLdapTemplate 中有使用这种自动翻译(往返于 ODM 注释的类)的新方法。请参阅 Object-Directory Mapping (ODM) 以了解更多信息。

  • 最终提供了自定义 XML 命名空间来简化 Spring LDAP 的配置。有关详细信息,请参阅 [configuration]

  • Spring LDAP 现在为 Spring Data Repository 和 QueryDSL 提供支持。有关详细信息,请参阅 Spring LDAP Repositories

  • 现在以 DirContextAdapter 和 ODM 中识别名相等性方面正确处理 Name 实例作为属性值。有关详细信息,请参阅 DirContextAdapter and Distinguished Names as Attribute ValuesODM and Distinguished Names as Attribute Values

  • DistinguishedName 已弃用,其相关类已弃用,支持标准的 Java LdapName。有关库在处理 LdapName 对象时的帮助的信息,请参阅 Dynamically Building Distinguished Names

  • 增加了流利的 LDAP 查询构建支持。当处理 Spring LDAP 中的 LDAP 搜索时,这将带来更愉快的编程体验。有关 LDAP 查询构建程序支持的更多信息,请参阅 Building LDAP QueriesAdvanced LDAP Queries

  • LdapTemplate 中旧的 authenticate 方法已弃用,支持几个新的 authenticate 方法,这些方法使用 LdapQuery 对象和 throw exceptions 处理身份验证失败,使用户更容易找到导致身份验证尝试失败的因素。

  • samples 已得到优化和更新,以便使用 2.0 中的功能。已付出大量努力提供了有用 的 LDAP user management application 示例。

Packaging Overview

最少情况下,要使用 Spring LDAP,您需要以下内容:

  • spring-ldap-core:Spring LDAP 库

  • spring-core:框架内部使用的各种实用程序类

  • spring-beans:用于操作 Java Bean 的接口和类

  • slf4j:一个简单的日志记录外观,在内部使用

除了必需的依赖项之外,还需要以下可选依赖项来实现特定功能:

  • spring-data-ldap:基础架构用于存储库支持等

  • spring-context:如果使用 Spring 应用上下文对应用进行连接,则需要。spring-context`会增加应用对象以一致的 API 获取资源的能力。如果你计划使用 `BaseLdapPathBeanPostProcessor,这肯定是必需的。

  • spring-tx:如果你打算使用客户端补偿事务支持,则需要。

  • spring-jdbc:如果你打算使用客户端补偿事务支持,则需要。

  • commons-pool:如果你打算使用连接池功能,则需要。

  • spring-batch:如果你打算将 LDIF 解析功能与 Spring Batch 一起使用,则需要。

spring-data-ldap 传递地添加了 spring-repository.xsd,其中 spring-ldap.xsd 使用。因此,Spring LDAP 的 XML 配置支持即使在不使用 Spring Data 的功能集的情况下也需要依赖项。

Getting Started

@"20" 提供了一些有用的示例,说明如何将 Spring LDAP 用于常见用例。

Support

如有问题,请在 @"22" 上提问。项目网页为 [role="bare"]@"23"。

Acknowledgements

启动 Spring LDAP 项目时的初期工作由 @"24" 赞助。项目的当前维护由 @"25" 资助,该公司已被 @"26" 收购。

感谢 @"27" 提供开源许可证,它在维护项目结构方面发挥了重要作用。