|
该版本仍在开发中,尚未被视为稳定。对于最新稳定版本,请使用 Spring LDAP 4.0.0! |
基本用途
使用搜索和查找属性映射器
以下示例使用了一个属性映射器构建一个包含所有人称对象常见名称的列表。
属性映射器返回一个属性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遍历所有找到的条目,调用给定的属性映射器每个条目,并收集结果并以列表形式呈现。然后列表由搜索方法。
注意属性映射器实现可以很容易地修改以返回完整的人目标,具体如下:
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中称为“查找”。以下示例展示了对 的查找人对象:
public class PersonRepoImpl implements PersonRepo {
private LdapClient ldapClient;
...
public Person findPerson(String dn) {
return ldapClient.search().name(dn).toObject(new PersonAttributesMapper());
}
}
前述示例查找指定的DN,并将找到的属性传递给所提供的属性映射器—— 在此情况下,结果为人对象。
构建LDAP查询
LDAP搜索涉及多个参数,包括以下几项:
-
基线LDAP路径:在LDAP树中搜索应从哪里开始。
-
搜索范围:搜索应该深入 LDAP 树的深度。
-
属性要返回。
-
搜索筛选器:在范围内选择元素时应使用的条件。
春季LDAP提供LdapQueryBuilder并配备了用于构建 LDAP 查询的流畅 API。
假设你想从底DN开始进行搜索DC=261consulting,dc=com,
限制返回属性为快递 之 家和锡,其中滤子为(&(objectclass=person)(sn=?)),其中我们希望?用 的值来替代姓氏参数。
以下示例展示了如何通过使用LdapQueryBuilder:
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查询。
动态构建卓越名称
Distinguished Name 的标准 Java 实现(LdapName(LdapName))
在解析杰出姓名时表现良好。然而,在实际应用中,这种实现存在若干不足:
-
这
LdapName(LdapName)实现是可变的,这并不适合表示身份的对象。 -
尽管具有可变性,但用于动态构建或修改卓越名称的 API,通过以下方式
LdapName(LdapName)很麻烦。 提取索引或(特别是)命名组件的值也有些不便。 -
许多作
LdapName(LdapName)抛出检查异常,要求尝试接球用于错误通常致命且无法有意义修复的情况。
为了简化与杰出人物的合作,Spring LDAP提供了LdapNameBuilder,
以及多种效用方法LdapUtils这在工作时很有帮助LdapName(LdapName).
例子
本节展示了前文章节中涵盖的一些主题示例。
第一个例子动态构建了LdapName(LdapName)通过LdapNameBuilder:
LdapName(LdapName)通过LdapNameBuilderimport 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();
}
...
}
假设人具有以下属性:
| 属性名称 | 属性值 |
|---|---|
|
瑞典 |
|
某人 |
|
某个人 |
前述代码随后形成以下显著名称:
cn=Some Person, ou=Some Company, c=Sweden, dc=example, dc=com
以下示例通过以下方式从一个区分名称中提取值LdapUtils
LdapUtilsimport 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)以及前面提到的公用设施。
绑定与解绑
本节描述如何添加和删除数据。更新内容将在下一节介绍。
添加数据
在 Java LDAP 中插入数据称为绑定。这有些令人困惑,因为在LDAP术语中,“bind”的含义完全不同。
JNDI 绑定执行 LDAP 添加作,将具有指定区分名称的新条目与一组属性关联起来。
以下示例通过以下方式添加数据LdapClient:
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.
更新
在 Java LDAP 中,数据可以通过两种方式修改:要么是重新绑定或者通过使用modifyAttributes.
通过使用重新绑定进行更新
一个重新绑定这是一种粗糙的修改数据方式。它基本上是㩠接着是捆.
以下示例调用LDAP的重新绑定:
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.该作需要一系列显式属性修改
并在特定曲目中表演,具体如下:
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为简化这些作提供了更多帮助。