Visão geral do Spring LDAP

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.

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”.