Panoramica di Spring LDAP

1. Panoramica

I server di directory LDAP sono archivi di dati gerarchici ottimizzati per la lettura. In genere, vengono utilizzati per archiviare le informazioni relative all'utente richieste per l'autenticazione e l'autorizzazione dell'utente.

In questo articolo esploreremo le API Spring LDAP per autenticare e cercare utenti, nonché per creare e modificare utenti nel server di directory. Lo stesso insieme di API può essere utilizzato per gestire qualsiasi altro tipo di voci in LDAP.

2. Dipendenze di Maven

Iniziamo aggiungendo la dipendenza Maven richiesta:

 org.springframework.ldap spring-ldap-core 2.3.1.RELEASE 

L'ultima versione di questa dipendenza può essere trovata su spring-ldap-core.

3. Preparazione dei dati

Ai fini di questo articolo, creiamo prima la seguente voce LDAP:

ou=users,dc=example,dc=com (objectClass=organizationalUnit)

Sotto questo nodo, creeremo nuovi utenti, modificheremo gli utenti esistenti, autenticheremo gli utenti esistenti e cercheremo informazioni.

4. API LDAP di primavera

4.1. Definizione bean ContextSource e LdapTemplate

ContextSource viene utilizzato per creare il LdapTemplate . Vedremo l'uso di ContextSource durante l'autenticazione dell'utente nella sezione successiva:

@Bean public LdapContextSource contextSource() { LdapContextSource contextSource = new LdapContextSource(); contextSource.setUrl(env.getRequiredProperty("ldap.url")); contextSource.setBase( env.getRequiredProperty("ldap.partitionSuffix")); contextSource.setUserDn( env.getRequiredProperty("ldap.principal")); contextSource.setPassword( env.getRequiredProperty("ldap.password")); return contextSource; }

LdapTemplate viene utilizzato per la creazione e la modifica delle voci LDAP:

@Bean public LdapTemplate ldapTemplate() { return new LdapTemplate(contextSource()); }

4.2. Autenticazione utente

Implementiamo ora un semplice pezzo di logica per autenticare un utente esistente:

public void authenticate(String username, String password) { contextSource .getContext( "cn=" + username + ",ou=users," + env.getRequiredProperty("ldap.partitionSuffix"), password); }

4.3. Creazione dell'utente

Successivamente, creiamo un nuovo utente e memorizziamo un hash SHA della password in LDAP.

Al momento dell'autenticazione, il server LDAP genera l'hash SHA della password fornita e lo confronta con quella memorizzata:

public void create(String username, String password) { Name dn = LdapNameBuilder .newInstance() .add("ou", "users") .add("cn", username) .build(); DirContextAdapter context = new DirContextAdapter(dn); context.setAttributeValues( "objectclass", new String[] { "top", "person", "organizationalPerson", "inetOrgPerson" }); context.setAttributeValue("cn", username); context.setAttributeValue("sn", username); context.setAttributeValue ("userPassword", digestSHA(password)); ldapTemplate.bind(context); }

digestSHA () è un metodo personalizzato che restituisce la stringa codificata Base64 dell'hash SHA della password fornita.

Infine, il metodo bind () di LdapTemplate viene utilizzato per creare una voce nel server LDAP.

4.4. Modifica dell'utente

Possiamo modificare un utente o una voce esistente con il seguente metodo:

public void modify(String username, String password) { Name dn = LdapNameBuilder.newInstance() .add("ou", "users") .add("cn", username) .build(); DirContextOperations context = ldapTemplate.lookupContext(dn); context.setAttributeValues ("objectclass", new String[] { "top", "person", "organizationalPerson", "inetOrgPerson" }); context.setAttributeValue("cn", username); context.setAttributeValue("sn", username); context.setAttributeValue("userPassword", digestSHA(password)); ldapTemplate.modifyAttributes(context); }

Il metodo lookupContext () viene utilizzato per trovare l'utente fornito.

4.5. Ricerca utente

Possiamo cercare gli utenti esistenti utilizzando i filtri di ricerca:

public List search(String username) { return ldapTemplate .search( "ou=users", "cn=" + username, (AttributesMapper) attrs -> (String) attrs.get("cn").get()); }

L'AttributesMapper viene utilizzato per ottenere il valore di attributo desiderato dai risultati trovati. Internamente, Spring LdapTemplate richiama AttributesMapper per tutte le voci trovate e crea un elenco dei valori degli attributi.

5. Test

spring-ldap-test fornisce un server LDAP integrato basato su ApacheDS 1.5.5. Per impostare il server LDAP incorporato per il test, è necessario configurare il seguente bean Spring:

@Bean public TestContextSourceFactoryBean testContextSource() { TestContextSourceFactoryBean contextSource = new TestContextSourceFactoryBean(); contextSource.setDefaultPartitionName( env.getRequiredProperty("ldap.partition")); contextSource.setDefaultPartitionSuffix( env.getRequiredProperty("ldap.partitionSuffix")); contextSource.setPrincipal( env.getRequiredProperty("ldap.principal")); contextSource.setPassword( env.getRequiredProperty("ldap.password")); contextSource.setLdifFile( resourceLoader.getResource( env.getRequiredProperty("ldap.ldiffile"))); contextSource.setPort( Integer.valueOf( env.getRequiredProperty("ldap.port"))); return contextSource; }

Testiamo il nostro metodo di ricerca utente con JUnit:

@Test public void givenLdapClient_whenCorrectSearchFilter_thenEntriesReturned() { List users = ldapClient .search(SEARCH_STRING); assertThat(users, Matchers.containsInAnyOrder(USER2, USER3)); }

6. Conclusione

In questo articolo abbiamo introdotto le API Spring LDAP e sviluppato metodi semplici per l'autenticazione utente, la ricerca utente, la creazione e la modifica dell'utente in un server LDAP.

Come sempre il codice sorgente completo è disponibile in questo progetto Github. I test vengono creati sotto il profilo Maven "live" e quindi possono essere eseguiti utilizzando l'opzione "-P live".