对于最新稳定版本,请使用 Spring LDAP 4.0.0spring-doc.cadn.net.cn

基本用途

使用搜索和查找属性映射器

以下示例使用了一个属性映射器构建一个包含所有人称对象常见名称的列表。spring-doc.cadn.net.cn

例子1。属性映射器返回一个属性
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"))
                .toList((Attributes attrs) -> (String) attrs.get("cn").get());
   }
}

的内联实现属性映射器属性Object并返回。内部LdapClient遍历所有找到的条目,调用给定的属性映射器每个条目,并收集结果并以列表形式呈现。然后列表由搜索方法。spring-doc.cadn.net.cn

注意属性映射器实现可以很容易地修改以返回完整的目标,具体如下:spring-doc.cadn.net.cn

例子2。返回 Person 对象的 AttributesMapper
import static org.springframework.ldap.query.LdapQueryBuilder.query;

public class PersonRepoImpl implements PersonRepo {
   private LdapClient ldapClient;
   ...
   private class PersonAttributesMapper implements AttributesMapper<Person> {
      public Person mapFromAttributes(Attributes attrs) throws NamingException {
         Person person = new Person();
         person.setFullName((String)attrs.get("cn").get());
         person.setLastName((String)attrs.get("sn").get());
         person.setDescription((String)attrs.get("description").get());
         return person;
      }
   }

   public List<Person> getAllPersons() {
      return ldapClient.search()
            .query(query().where("objectclass").is("person"))
            .toList(new PersonAttributesMapper());
   }
}

LDAP中的条目通过其特殊名称(DN)唯一标识。 如果你有条目的DN,可以直接检索该条目,无需查询。 这在Java LDAP中称为“查找”。以下示例展示了对 的查找对象:spring-doc.cadn.net.cn

例子3。查找结果是一个Person对象
public class PersonRepoImpl implements PersonRepo {
   private LdapClient ldapClient;
   ...
   public Person findPerson(String dn) {
      return ldapClient.search().name(dn).toObject(new PersonAttributesMapper());
   }
}

前述示例查找指定的DN,并将找到的属性传递给所提供的属性映射器—— 在此情况下,结果为对象。spring-doc.cadn.net.cn

构建LDAP查询

LDAP搜索涉及多个参数,包括以下几项:spring-doc.cadn.net.cn

春季LDAP提供LdapQueryBuilder并配备了用于构建 LDAP 查询的流畅 API。spring-doc.cadn.net.cn

假设你想从底DN开始进行搜索DC=261consulting,dc=com, 限制返回属性为快递 之 家,其中滤子为(&(objectclass=person)(sn=?)),其中我们希望?用 的值来替代姓氏参数。 以下示例展示了如何通过使用LdapQueryBuilder:spring-doc.cadn.net.cn

例子4。动态构建搜索筛选器
import static org.springframework.ldap.query.LdapQueryBuilder.query;

public class PersonRepoImpl implements PersonRepo {
   private LdapClient ldapClient;
   ...
   public List<String> getPersonNamesByLastName(String lastName) {

      LdapQuery query = query()
         .base("dc=261consulting,dc=com")
         .attributes("cn", "sn")
         .where("objectclass").is("person")
         .and("sn").is(lastName);

      return ldapClient.search().query(query)
            .toObject((Attributes attrs) -> (String) attrs.get("cn").get());
   }
}
除了简化复杂搜索参数的构建外,LdapQueryBuilder其相关类还能正确规避搜索筛选中任何不安全的字符。这防止了“LDAP注入”,即用户可能使用此类字符向你的LDAP作注入不需要的作。
LdapClient包含许多用于执行 LDAP 搜索的超载方法。这是为了尽可能适应不同的用例和编程风格偏好。对于绝大多数用例,采用LdapQuery以下是推荐的方法。
属性映射器只是处理搜索和查找数据时可用的回调接口之一。 看简化属性访问和作DirContextAdapter为了替代方案。

欲了解更多关于LdapQueryBuilder,参见高级LDAP查询spring-doc.cadn.net.cn

动态构建卓越名称

Distinguished Name 的标准 Java 实现(LdapName(LdapName)) 在解析区分名称方面表现良好。然而,在实际应用中,该实现存在若干不足:spring-doc.cadn.net.cn

  • LdapName(LdapName)实现是可变的,这并不适合表示身份的对象。spring-doc.cadn.net.cn

  • 尽管具有可变性,但用于动态构建或修改卓越名称的 API,通过以下方式LdapName(LdapName)很繁琐。提取索引组件或(特别是)命名组件的值也有些不便。spring-doc.cadn.net.cn

  • 许多作LdapName(LdapName)抛出检查异常,要求尝试接球用于错误通常致命且无法有意义修复的情况。spring-doc.cadn.net.cn

为了简化与杰出人物的合作,Spring LDAP提供了LdapNameBuilder, 以及多种效用方法LdapUtils这在工作时很有帮助LdapName(LdapName).spring-doc.cadn.net.cn

例子

本节展示了前文章节中涉及的几个主题示例。第一个示例动态构建了LdapName(LdapName)通过LdapNameBuilder:spring-doc.cadn.net.cn

示例5。动态构建一个LdapName(LdapName)通过LdapNameBuilder
import org.springframework.ldap.support.LdapNameBuilder;
import javax.naming.Name;

public class PersonRepoImpl implements PersonRepo {
  public static final String BASE_DN = "dc=example,dc=com";

  protected Name buildDn(Person p) {
    return LdapNameBuilder.newInstance(BASE_DN)
      .add("c", p.getCountry())
      .add("ou", p.getCompany())
      .add("cn", p.getFullname())
      .build();
  }
  ...
}

假设具有以下属性:spring-doc.cadn.net.cn

属性名称 属性值

状态spring-doc.cadn.net.cn

瑞典spring-doc.cadn.net.cn

公司spring-doc.cadn.net.cn

某人spring-doc.cadn.net.cn

全名spring-doc.cadn.net.cn

某个人spring-doc.cadn.net.cn

前述代码随后形成以下显著名称:spring-doc.cadn.net.cn

cn=Some Person, ou=Some Company, c=Sweden, dc=example, dc=com

以下示例通过以下方式从一个区分名称中提取值LdapUtilsspring-doc.cadn.net.cn

示例6。通过以下方式从区分名称中提取值LdapUtils
import org.springframework.ldap.support.LdapNameBuilder;
import javax.naming.Name;
public class PersonRepoImpl implements PersonRepo {
...
  protected Person buildPerson(Name dn, Attributes attrs) {
    Person person = new Person();
    person.setCountry(LdapUtils.getStringValue(dn, "c"));
    person.setCompany(LdapUtils.getStringValue(dn, "ou"));
    person.setFullname(LdapUtils.getStringValue(dn, "cn"));
    // Populate rest of person object using attributes.

    return person;
  }
}

由于 1.4 之前及包括 Java 版本根本不提供任何公开的 Distinguished Name 实现,Spring LDAP 1.x 提供了自己的实现,杰出名号. 该实现存在一些自身缺陷,已在2.0版本中被弃用。你现在应该使用LdapName(LdapName)以及前面提到的公用设施。spring-doc.cadn.net.cn

绑定与解绑

本节介绍如何添加和删除数据。更新将在下一节介绍。spring-doc.cadn.net.cn

添加数据

在Java LDAP中插入数据称为绑定。这有些令人困惑,因为在LDAP术语中,“绑定”的含义完全不同。JNDI绑定执行LDAP添加作,将带有指定区分名称的新条目与一组属性关联起来。以下示例通过以下方式添加数据LdapClient:spring-doc.cadn.net.cn

示例7。使用属性添加数据
public class PersonRepoImpl implements PersonRepo {
   private LdapClient ldapClient;
   ...
   public void create(Person p) {
      Name dn = buildDn(p);
      ldapClient.bind(dn).attributes(buildAttributes(p)).execute();
   }

   private Attributes buildAttributes(Person p) {
      Attributes attrs = new BasicAttributes();
      BasicAttribute ocattr = new BasicAttribute("objectclass");
      ocattr.add("top");
      ocattr.add("person");
      attrs.put(ocattr);
      attrs.put("cn", "Some Person");
      attrs.put("sn", "Person");
      return attrs;
   }
}

手动属性构建虽然枯燥冗长,但对许多用途来说已经足够了。不过,你可以进一步简化绑定作,如以下所述简化属性访问和作DirContextAdapter.spring-doc.cadn.net.cn

数据移除

在 Java LDAP 中移除数据称为解绑。JNDI 解绑执行 LDAP 删除作,从指定区分名称树中移除与该名称相关的条目。以下示例通过以下方式移除数据LdapClient:spring-doc.cadn.net.cn

示例8。移除数据
public class PersonRepoImpl implements PersonRepo {
   private LdapClient ldapClient;
   ...
   public void delete(Person p) {
      Name dn = buildDn(p);
      ldapClient.unbind(dn).execute();
   }
}

更新

在 Java LDAP 中,数据可以通过两种方式修改:要么是重新绑定或者通过使用modifyAttributes.spring-doc.cadn.net.cn

通过使用重新绑定进行更新

一个重新绑定这是一种粗略的修改数据方式。它基本上是接着是. 以下示例调用LDAP的重新绑定:spring-doc.cadn.net.cn

示例9。使用重绑定进行修改
public class PersonRepoImpl implements PersonRepo {
   private LdapClient ldapClient;
   ...
   public void update(Person p) {
      Name dn = buildDn(p);
      ldapTemplate.bind(dn).attributes(buildAttributes(p)).replaceExisting(true).execute();
   }
}

通过使用更新modifyAttributes

更复杂的数据修改方式是modifyAttributes. 该作对一个显式属性修改数组并对特定条目执行,具体如下:spring-doc.cadn.net.cn

示例10。使用modifyAttributes进行修改
public class PersonRepoImpl implements PersonRepo {
   private LdapClient ldapClient;
   ...
   public void updateDescription(Person p) {
      Name dn = buildDn(p);
      Attribute attr = new BasicAttribute("description", p.getDescription())
      ModificationItem item = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, attr);
      ldapTemplate.modify().name(dn).attributes(item).execute();
   }
}

架构属性修改物品数组工作量很大。然而,正如我们在简化属性访问和作DirContextAdapter, Spring LDAP为简化这些作提供了更多帮助。spring-doc.cadn.net.cn