简介

概述

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

  • 类似于 JdbcTemplate 的模板简化 LDAP 编程。

  • JPA 或 Hibernate 风格的基于注解的对象与目录映射。

  • Spring Data 仓库支持,包括 QueryDSL 支持。

  • 简化 LDAP 查询和可分辨名称构建的实用工具。

  • 适当的 LDAP 连接池。

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

传统 Java LDAP 与 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://: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 Framework 的子项目,我们使用 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://: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 声明中包含对此命名空间的引用,如上例所示。

2.2 版本的新特性

有关 2.2 的完整详细信息,请参阅 2.2.0.RC1 的变更日志。Spring LDAP 2.2 的亮点如下:

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

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

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

2.1 版本的新特性

有关 2.1 的完整详细信息,请参阅 2.1.0.RC12.1.0 的变更日志。Spring LDAP 2.1 的亮点如下。

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

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

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

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

  • #401:切换到 assertj

  • 从 JIRA 迁移到 GitHub Issues

  • 增加了 Gitter Chat

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 中最重要的更改:

  • Spring LDAP 现在需要 Java 6。Spring 2.0 及更高版本仍然受支持。

  • 核心 API 已更新,支持 Java 5+ 特性,如泛型和可变参数。因此,整个 spring-ldap-tiger 模块已被弃用,我们鼓励您迁移到使用核心 Spring LDAP 类。核心接口的参数化会导致现有代码中出现大量编译警告,我们鼓励您采取适当措施来消除这些警告。

  • ODM(对象目录映射)功能已移至核心,并且 LdapOperationsLdapTemplate 中有新方法使用这种到 ODM 注解类的自动转换。有关更多信息,请参阅 对象目录映射 (ODM)

  • 现在(终于)提供了自定义 XML 命名空间以简化 Spring LDAP 的配置。有关更多信息,请参阅 [配置]

  • Spring LDAP 现在支持 Spring Data Repository 和 QueryDSL。有关更多信息,请参阅 Spring LDAP 仓库

  • DirContextAdapter 和 ODM 中,Name 实例作为属性值现在已针对可分辨名称相等性得到正确处理。有关更多信息,请参阅 DirContextAdapter 和作为属性值的可分辨名称以及 ODM 和作为属性值的可分辨名称

  • DistinguishedName 及相关类已弃用,取而代之的是标准的 Java LdapName。有关该库如何帮助使用 LdapName 对象的信息,请参阅 动态构建可分辨名称

  • 已添加流畅的 LDAP 查询构建支持。这使得在 Spring LDAP 中处理 LDAP 搜索时编程体验更加愉快。有关 LDAP 查询构建器支持的更多信息,请参阅 构建 LDAP 查询高级 LDAP 查询

  • LdapTemplate 中旧的 authenticate 方法已被弃用,取而代之的是几个新的 authenticate 方法,它们与 LdapQuery 对象一起使用,并在身份验证失败时抛出异常,从而使用户更容易找出导致身份验证尝试失败的原因。

  • 示例已进行了完善和更新,以利用 2.0 中的功能。为了提供一个有用的 LDAP 用户管理应用程序示例,投入了相当多的精力。

  • 添加了 LdapClient.create(LdapTemplate) 以简化从 LdapTemplate 构造 LdapClient

打包概述

至少,要使用 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.xsdspring-ldap.xsd 使用了它。因此,即使不使用 Spring Data 的功能集,Spring LDAP 的 XML 配置支持也需要此依赖项。

入门

示例提供了一些关于如何将 Spring LDAP 用于常见用例的有用示例。

支持

如果您有任何问题,请在 Stack Overflow 上使用 spring-ldap 标签提问。项目网页是 spring.io/spring-ldap/

致谢

Spring LDAP 项目启动时的最初努力由 Jayway 赞助。该项目的当前维护由 Pivotal 资助,该公司后来被 VMware 收购。

感谢 Structure101 提供了开源许可证,这对保持项目结构井然有序非常有用。

© . This site is unofficial and not affiliated with VMware.