Spring LDAP Обзор

Spring LDAP Обзор

1. обзор

Серверы каталогов LDAP являются оптимизированными для чтения иерархическими хранилищами данных. Обычно они используются для хранения связанной с пользователем информации, необходимой для аутентификации и авторизации пользователей.

В этой статье мы рассмотрим API-интерфейсы Spring LDAP для аутентификации и поиска пользователей, а также для создания и изменения пользователей на сервере каталогов. Тот же набор API можно использовать для управления записями любого другого типа в LDAP.

2. Maven Зависимости

Начнем с добавления необходимой зависимости Maven:


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

Последнюю версию этой зависимости можно найти по адресуspring-ldap-core.

3. Подготовка данных

Для целей этой статьи давайте сначала создадим следующую запись LDAP:

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

Под этим узлом мы будем создавать новых пользователей, изменять существующих пользователей, проверять подлинность существующих пользователей и искать информацию.

4. API Spring LDAP

4.1. ContextSource &LdapTemplate Определение компонента

ContextSource используется для созданияLdapTemplate. Мы увидим использованиеContextSource во время аутентификации пользователя в следующем разделе:

@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 используется для создания и изменения записей LDAP:

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

4.2. Аутентификация пользователя

Давайте теперь реализуем простую часть логики для аутентификации существующего пользователя:

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

4.3. Создание пользователя

Затем давайте создадим нового пользователя и сохраним SHA-хэш пароля в LDAP.

Во время аутентификации сервер LDAP генерирует хэш SHA предоставленного пароля и сравнивает его с сохраненным:

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() - это специальный метод, который возвращает закодированную в Base64 строку хэша SHA предоставленного пароля.

Наконец, методbind()LdapTemplate используется для создания записи на сервере LDAP.

4.4. Модификация пользователя

Мы можем изменить существующего пользователя или запись следующим способом:

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

МетодlookupContext() используется для поиска указанного пользователя.

Мы можем искать существующих пользователей, используя поисковые фильтры:

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

AttributesMapper используется для получения желаемого значения атрибута из найденных записей. Внутри SpringLdapTemplate вызываетAttributesMapper для всех найденных записей и создает список значений атрибутов.

5. тестирование

spring-ldap-test предоставляет встроенный LDAP-сервер на основе ApacheDS 1.5.5. Чтобы настроить встроенный сервер LDAP для тестирования, нам нужно настроить следующий 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;
}

Давайте протестируем наш метод поиска пользователей с помощью JUnit:

@Test
public void
  givenLdapClient_whenCorrectSearchFilter_thenEntriesReturned() {
    List users = ldapClient
      .search(SEARCH_STRING);

    assertThat(users, Matchers.containsInAnyOrder(USER2, USER3));
}

6. Заключение

В этой статье мы представили Spring LDAP API и разработали простые методы для аутентификации пользователей, поиска пользователей, создания и модификации пользователей на сервере LDAP.

Как всегда, полный исходный код доступен вthis Github project. Тесты создаются в профиле Maven «live» и, следовательно, могут быть запущены с помощью опции «-P live».