2016-06-21 22 views
0

Имея следующую организационную структуру в корпоративной Active Directory;Spring LdapTemplate поиск на нескольких базах с отдельными фильтрами

  • DC = Foo, DC = бар, DC = ком
    • OU = сотрудники
      • CN = employee1
      • CN = employee2
    • OU = интерны
      • CN = intern1
      • CN = intern2
    • OU = х
    • OU = у
    • OU = г

мне нужно, чтобы получить единый список из;

сотрудники, имеющие атрибут "А" и не, имеющий атрибут "B" и интерны, имеющие атрибут "B" и не, имеющий атрибут "A".

Создание Spring LDAP-LdapContextSource установки DC = Foo, DC = бара, DC = ком в качестве основы, я не могу видеть API поиска на LdapTemplate для установки нескольких баз поиска, имеющих отдельные фильтры.

Образец кода, который не дает никаких совпадений;

@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() и не устанавливать отдельные фильтры на базу.

Любые идеи по выполнению этого запроса за один шаг?

+0

Хотя конфигурация Spring LDAP прямолинейна, я вставил примерный код в любом случае в соответствии с комментарием @ TobySpeight. –

+1

Либо вы начинаете поиск выше в дереве, на обычном узле предка, либо выполняете его в двух отдельных поисках и присоединяете к ним результаты послесловия. – marthursson

+0

Спасибо за комментарий @marthursson. Я уже пробовал в обоих направлениях, и явным образом увеличилось время запроса.Однако в моем случае из-за перегруженной и не очень хорошо структурированной структуры AD, быстрее выполнить два отдельных запроса. Это логика в моем приложении на данный момент. –

ответ

0

Вы можете фильтровать элемент, в котором его подразделение является DirectoryConstants.EMPLOYEES с LdapQuery.base (DirectoryConstants.EMPLOYEES). В приведенном ниже коде показано, что найти все элементы, которые его OU является «dev», а атрибут с именем objectClass - «группа».

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(); 
     } 
    });