【发布时间】:2016-10-23 03:36:42
【问题描述】:
在企业 Active Directory 中具有以下组织结构;
- DC=foo,DC=bar,DC=com
- OU=员工
- CN=employee1
- CN=employee2
- OU=实习生
- CN=实习生1
- CN=实习生2
- OU=x
- OU=y
- OU=z
我需要检索单个列表;
具有“A”属性且不具有“B”属性的员工 以及具有“B”属性且不具有“A”属性的实习生。
通过将 DC=foo,DC=bar,DC=com 设置为基础来生成 Spring LDAP 的 LdapContextSource,我在 LdapTemplate 上看不到任何用于设置多个搜索基础的搜索 API单独的过滤器。
这是一个不返回任何匹配的示例代码;
@Configuration
public class LdapConfiguration {
@Autowired
Environment env;
@Bean
public LdapContextSource contextSource () {
LdapContextSource contextSource= new LdapContextSource();
contextSource.setUrl(env.getRequiredProperty("ldap.url"));
contextSource.setBase("DC=foo,DC=bar,DC=com");
contextSource.setUserDn(env.getRequiredProperty("ldap.user"));
contextSource.setPassword(env.getRequiredProperty("ldap.password"));
return contextSource;
}
@Bean
public LdapTemplate ldapTemplate() {
return new LdapTemplate(contextSource());
}
private List<Contact> ldapsearch(AndFilter filter) {
OrFilter orFilter = new OrFilter();
// EMPLOYEE FILTER
AndFilter employeesFilter = new AndFilter();
employeesFilter.and(filter);
// ou=employees
employeesFilter.and(new EqualsFilter(DirectoryConstants.OU, DirectoryConstants.EMPLOYEES));
// A=*
employeesFilter.and(new PresentFilter(DirectoryConstants.A));
// (!(B=*))
employeesFilter.and(new NotPresentFilter(DirectoryConstants.B));
// INTERN FILTER
AndFilter internFilter = new AndFilter();
internFilter.and(filter);
// ou=interns
internFilter.and(new EqualsFilter(DirectoryConstants.OU, DirectoryConstants.INTERNS));
// (!(A=*))
internFilter.and(new NotPresentFilter(DirectoryConstants.A));
// (B=*)
internFilter.and(new PresentFilter(DirectoryConstants.B));
orFilter.or(employeesFilter);
orFilter.or(internFilter);
List<Contact> contacts = null;
try {
contacts = ldapTemplate().search(
"",
orFilter.encode(),
new AttributesMapper<Contact>() {
public Contact mapFromAttributes(Attributes attrs) throws NamingException {
return buildContact(attrs);
}
});
} catch (Exception e) {
logger.error("Active directory search failed. " + e.getMessage());
}
return contacts;
}
}
我认为上面的过滤器ou=employees 和ou=interns 不应该是过滤器的一部分,而应该是base 的一部分(ldapTemplate().search() 的第一个参数)。但是,我找不到任何 API,既不能将多个基数设置为 ldapTemplate().search(),也不能为每个基数设置单独的过滤器。
关于单步执行此查询的任何想法?
【问题讨论】:
-
虽然 Spring LDAP 的配置很简单,但我还是按照@TobySpeight 的评论插入了一个示例代码。
-
要么在树的较高位置开始搜索,在一个共同的祖先节点处,要么在两个单独的搜索中进行搜索,然后加入结果。
-
感谢@marthursson 的评论。我已经尝试了两种方法,很明显两者都增加了查询时间。然而,在我的例子中,由于公司 AD 结构过载且结构不佳,执行两个单独的查询会更快。这是我现在应用程序中的逻辑。
标签: java spring spring-ldap