Descripción general de Spring LDAP

1. Información general

Los servidores de directorio LDAP son almacenes de datos jerárquicos optimizados para lectura. Por lo general, se utilizan para almacenar información relacionada con el usuario necesaria para la autenticación y autorización del usuario.

En este artículo, exploraremos las API de Spring LDAP para autenticar y buscar usuarios, así como para crear y modificar usuarios en el servidor de directorio. El mismo conjunto de API se puede utilizar para administrar cualquier otro tipo de entradas en LDAP.

2. Dependencias de Maven

Comencemos agregando la dependencia de Maven requerida:

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

La última versión de esta dependencia se puede encontrar en spring-ldap-core.

3. Preparación de datos

Para el propósito de este artículo, primero creemos la siguiente entrada LDAP:

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

Bajo este nodo, crearemos nuevos usuarios, modificaremos usuarios existentes, autenticaremos usuarios existentes y buscaremos información.

4. API de Spring LDAP

4.1. Definición de Bean ContextSource y LdapTemplate

ContextSource se utiliza para crear LdapTemplate . Veremos el uso de ContextSource durante la autenticación del usuario en la siguiente sección:

@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 se utiliza para la creación y modificación de entradas LDAP:

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

4.2. Autenticacion de usuario

Implementemos ahora una simple pieza de lógica para autenticar a un usuario existente:

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

4.3. Creación de usuarios

A continuación, creemos un nuevo usuario y almacenemos un hash SHA de la contraseña en LDAP.

En el momento de la autenticación, el servidor LDAP genera el hash SHA de la contraseña proporcionada y la compara con la almacenada:

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 () es un método personalizado que devuelve la cadena codificada en Base64 del hash SHA de la contraseña proporcionada.

Finalmente, el método bind () de LdapTemplate se usa para crear una entrada en el servidor LDAP.

4.4. Modificación de usuario

Podemos modificar un usuario o entrada existente con el siguiente método:

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

El método lookupContext () se utiliza para encontrar el usuario proporcionado.

4.5. Búsqueda de usuario

Podemos buscar usuarios existentes usando filtros de búsqueda:

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

El AttributesMapper se utiliza para obtener el valor del atributo deseado de las entradas encontradas. Internamente, Spring LdapTemplate invoca AttributesMapper para todas las entradas encontradas y crea una lista de los valores de los atributos.

5. Prueba

spring-ldap-test proporciona un servidor LDAP integrado basado en ApacheDS 1.5.5. Para configurar el servidor LDAP incorporado para la prueba, necesitamos configurar el siguiente 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; }

Probemos nuestro método de búsqueda de usuarios con JUnit:

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

6. Conclusión

En este artículo, presentamos las API de Spring LDAP y desarrollamos métodos simples para la autenticación de usuarios, búsqueda de usuarios, creación y modificación de usuarios en un servidor LDAP.

Como siempre, el código fuente completo está disponible en este proyecto de Github. Las pruebas se crean bajo el perfil de Maven "en vivo" y, por lo tanto, se pueden ejecutar utilizando la opción "-P en vivo".