【问题标题】:Spring LdapTemplate search on multiple bases with separate filters使用单独的过滤器在多个基础上进行 Spring LdapTemplate 搜索
【发布时间】: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=employeesou=interns 不应该是过滤器的一部分,而应该是base 的一部分(ldapTemplate().search() 的第一个参数)。但是,我找不到任何 API,既不能将多个基数设置为 ldapTemplate().search(),也不能为每个基数设置单独的过滤器。

关于单步执行此查询的任何想法?

【问题讨论】:

  • 虽然 Spring LDAP 的配置很简单,但我还是按照@TobySpeight 的评论插入了一个示例代码。
  • 要么在树的较高位置开始搜索,在一个共同的祖先节点处,要么在两个单独的搜索中进行搜索,然后加入结果。
  • 感谢@marthursson 的评论。我已经尝试了两种方法,很明显两者都增加了查询时间。然而,在我的例子中,由于公司 AD 结构过载且结构不佳,执行两个单独的查询会更快。这是我现在应用程序中的逻辑。

标签: java spring spring-ldap


【解决方案1】:

您可以使用 LdapQuery.base(DirectoryConstants.EMPLOYEES) 过滤其 OU 为 DirectoryConstants.EMPLOYEES 的项目。下面的代码显示了查找所有其 OU 为 'dev' 且名为 objectClass 的属性为 'group' 的项目。

LdapQuery query = LdapQueryBuilder.query()
            .base("ou=dev")
            .where("objectClass").is("group");

    return ldapTemplate.search(query, new AttributesMapper<String>() {
        @Override
        public String mapFromAttributes(Attributes attributes) throws NamingException {
            return (String) attributes.get("cn").get();
        }
    });

【讨论】:

    猜你喜欢
    • 2020-01-01
    • 2019-07-14
    • 2019-04-25
    • 1970-01-01
    • 2020-10-28
    • 1970-01-01
    • 2011-09-06
    • 1970-01-01
    • 2019-08-15
    相关资源
    最近更新 更多