Visão geral do Spring LDAP
1. Visão geral
Os servidores de diretório LDAP são armazenamentos de dados hierárquicos otimizados para leitura. Normalmente, eles são usados para armazenar informações relacionadas ao usuário, necessárias para autenticação e autorização do usuário.
Neste artigo, exploraremos as APIs do Spring LDAP para autenticar e pesquisar usuários, bem como para criar e modificar usuários no servidor de diretório. O mesmo conjunto de APIs pode ser usado para gerenciar qualquer outro tipo de entrada no LDAP.
2. Dependências do Maven
Vamos começar adicionando a dependência necessária do Maven:
org.springframework.ldap
spring-ldap-core
2.3.1.RELEASE
A versão mais recente dessa dependência pode ser encontrada emspring-ldap-core.
3. Preparação de dados
Para os fins deste artigo, vamos primeiro criar a seguinte entrada LDAP:
ou=users,dc=example,dc=com (objectClass=organizationalUnit)
Sob esse nó, criaremos novos usuários, modificaremos os usuários existentes, autenticaremos os usuários existentes e buscaremos informações.
4. APIs Spring LDAP
4.1. ContextSource &LdapTemplate Definição de feijão
ContextSource é usado para criarLdapTemplate. Veremos o uso deContextSource durante a autenticação do usuário na próxima seção:
@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 é usado para criação e modificação de entradas LDAP:
@Bean
public LdapTemplate ldapTemplate() {
return new LdapTemplate(contextSource());
}
4.2. Autenticação de usuário
Vamos agora implementar uma peça simples de lógica para autenticar um usuário existente:
public void authenticate(String username, String password) {
contextSource
.getContext(
"cn=" +
username +
",ou=users," +
env.getRequiredProperty("ldap.partitionSuffix"), password);
}
4.3. Criação de usuário
A seguir, vamos criar um novo usuário e armazenar um hash SHA da senha no LDAP.
No momento da autenticação, o servidor LDAP gera o hash SHA da senha fornecida e a compara com a senha armazenada:
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() é um método personalizado que retorna a string codificada em Base64 do hash SHA da senha fornecida.
Finalmente, o métodobind() deLdapTemplate é usado para criar uma entrada no servidor LDAP.
4.4. Modificação do usuário
Podemos modificar um usuário ou entrada existente com o seguinte 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);
}
O métodolookupContext() é usado para encontrar o usuário fornecido.
4.5. Pesquisa de usuário
Podemos procurar usuários existentes usando filtros de pesquisa:
public List search(String username) {
return ldapTemplate
.search(
"ou=users",
"cn=" + username,
(AttributesMapper) attrs -> (String) attrs.get("cn").get());
}
OAttributesMapper é usado para obter o valor de atributo desejado das entradas encontradas. Internamente, SpringLdapTemplate invocaAttributesMapper para todas as entradas encontradas e cria uma lista de valores de atributos.
5. Teste
spring-ldap-test fornece um servidor LDAP integrado baseado no ApacheDS 1.5.5. Para configurar o servidor LDAP incorporado para teste, precisamos configurar o seguinte Spring bean:
@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;
}
Vamos testar nosso método de pesquisa de usuário com JUnit:
@Test
public void
givenLdapClient_whenCorrectSearchFilter_thenEntriesReturned() {
List users = ldapClient
.search(SEARCH_STRING);
assertThat(users, Matchers.containsInAnyOrder(USER2, USER3));
}
6. Conclusão
Neste artigo, introduzimos as APIs Spring LDAP e desenvolvemos métodos simples para autenticação, pesquisa e criação e modificação de usuários em um servidor LDAP.
Como sempre, o código-fonte completo está disponível emthis Github project. Os testes são criados no perfil Maven “live” e, portanto, podem ser executados usando a opção “-P live”.