2016-06-21 15 views
0

Mit der folgenden organisatorischen Struktur im Active Directory des Unternehmens;Spring LdapTemplate Suche auf mehreren Basen mit separaten Filtern

  • DC = foo, DC = bar, DC = com
    • OU = Mitarbeiter
      • CN = employee1
      • CN = employee2
    • OU = Praktikanten
      • CN = Intern1
      • CN = Intern2
    • OU = x
    • OU = y
    • OU = z

Ich brauche eine einzige Liste abrufen von;

Mitarbeiter mit Attribut "A" und nicht mit Attribut "B" und Praktikanten Attribut "B" aufweist und nicht mit Attribut "A".

generieren Frühling LDAP des LdapContextSource indem DC = foo, DC = bar, DC = com als Basis, kann ich auf LdapTemplate sehen jede Suche API nicht für mehrere Suchbereiche mit einzelnen Filter zu setzen.

Hier ist ein Beispielcode, der keine Übereinstimmungen zurückgibt;

@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; 
} 
} 

Ich glaube, die Filter ou=employees und ou=interns oben nicht Teil des Filters sein sollte, stattdessen sollten sie Teil des base (erster Parameter von ldapTemplate().search()) sein. Allerdings konnte ich keine API finden, um weder mehrere Basen auf ldapTemplate().search() zu setzen noch einzelne Filter pro Basis zu setzen.

Irgendwelche Ideen zum Ausführen dieser Abfrage in einem Schritt?

+0

Obwohl die LDAP-Konfiguration von Spring einfach ist, habe ich einen Beispielcode wie im @ TobySpeight-Kommentar eingefügt. –

+1

Entweder starten Sie Ihre Suche weiter oben im Baum, an einem gemeinsamen Vorfahrenknoten, oder Sie tun es in zwei separaten Suchen und verbinden die Ergebnisse danach. – marthursson

+0

Danke für den Kommentar @ Marthursson. Ich habe bereits beide Möglichkeiten ausprobiert und als offensichtlich beide die Abfragezeit erhöht.In meinem Fall ist es jedoch wegen der überladenen und nicht sehr gut strukturierten Unternehmens-AD-Struktur schneller, zwei getrennte Abfragen durchzuführen. Dies ist die Logik in meiner Anwendung ab sofort. –

Antwort

0

Sie können Element filtern, das seine OU DirectoryConstants.EMPLOYEES mit der LdapQuery.base (DirectoryConstants.EMPLOYEES) ist. Der folgende Code zeigt, dass alle Elemente gefunden werden, deren Organisationseinheit "dev" ist und das Attribut "objectClass" heißt "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(); 
     } 
    });