Spring LDAP — как управлять закодированным (SHA) паролем

Я хочу реализовать базовый пользовательский репозиторий с использованием Spring LDAP и его концепции сопоставления объектов и каталогов (ODM).

Мой пользовательский класс довольно прост:

@Entry(objectClasses = { "inetOrgPerson", "organizationalPerson", "person", "shadowAccount", "top" }, base = "ou=people")
public class User {
    [...]

    @Id
    private Name dn;

    @Attribute(name = "uid")
    @DnAttribute(value = "uid")
    private String username;

    @Attribute(name = "cn")
    private String fullName;

    @Attribute(name = "givenName")
    private String firstName;

    @Attribute(name = "sn")
    private String lastName;

    @Attribute(name = "o")
    private String organization;

    @Attribute(name = "userPassword")
    private String password;

    // Getters & Setters
    [...]
}

И основные методы моего репозитория:

public User findByUid(String uid) {
    return ldapTemplate.findOne(query().where("uid").is(uid), User.class);
}

public void update(User user) {
    ldapTemplate.update(user);
}

Все работает нормально, кроме атрибута пароля. Например, если я изменяю только имя пользователя, пароль также изменяется.

Я хочу знать, как работать с зашифрованным паролем (используя SHA — алгоритм безопасного хеширования).

Я не вижу никаких аннотаций, позволяющих указать метод кодирования.

Должны ли мы иметь дело с этим вручную?


person Fred    schedule 27.08.2014    source источник
comment
SHA — это метод шифрования, это безопасный алгоритм хеширования.   -  person user207421    schedule 28.08.2014
comment
Я имею в виду, что пароли шифруются с использованием этого алгоритма в OpenLDAP.   -  person Fred    schedule 28.08.2014
comment
Нет, вы имеете в виду, что пароли хэшируются с использованием этого алгоритма в OpenLDAP. Пароли не шифруются ни в одной системе с претензией на надлежащую безопасность. Вам не нужно указывать алгоритм хеширования в коде. Он настроен в OpenLDAP.   -  person user207421    schedule 28.08.2014


Ответы (1)


Укороченная версия

@Attribute(name = "userPassword", type = Type.BINARY)
private byte[] password;

является правильным определением вашего атрибута пароля. Это связано с тем, что LDAP также хранит пароль в двоичном виде.

Чтобы обеспечить удобный способ взаимодействия, вы должны изменить сеттер для password

public void setPassword(String password) {
    this.password = password.getBytes(Charset.forName("UTF-8"));
}

Длинная версия

Проблема в вашем определении userPassword. Это java.lang.String. А аннотация Spring LDAP ODM Attribute по умолчанию имеет значение Type.STRING.

Ваш LDAP получает строку в виде массива байтов и проверяет, имеет ли она правильный префикс (в нашем случае {SSHA}). Если префикс отсутствует, он хэширует данную строку с помощью настроенного алгоритма хеширования и сохраняет ее в атрибуте как двоичный файл. Здесь лежит первопричина. Ваше определение атрибута отличается. У LDAP есть двоичный файл, у вас есть строка.

Когда вы снова читаете запись, чтобы изменить имя, атрибут пароля также считывается. Но, поскольку в объекте должна быть строка, Spring преобразует двоичный массив в строку. Это преобразование неверно, так как оно создает строку.

e.g.

  • вы помещаете test в поле пароля вашего объекта сущности.
  • Spring берет строку и отправляет ее без изменений на сервер LDAP.
  • сервер хэширует строку и сохраняет ее как {SSHA}H97JD...
  • ты прочитай запись еще раз
  • spring получает byte[], содержащий числа ascii, представляющие сохраненное значение

    [123, 83, 83, 72, 65, 125, 72, 57, 55, 74, 68, ...]

  • преобразование в строку приводит к следующему:

    123,83,83,72,65,125,72,57,55,74,68,...

  • spring устанавливает эту строку в вашей сущности как значение пароля

  • вы меняете имя
  • spring снова берет строку пароля и отправляет ее как есть на сервер
  • проверка префикса сервера указывает на нехешированный пароль и снова применяет алгоритм хеширования к строке, потому что 123,83, начинается не с {SSHA}
  • сервер снова меняет пароль.
person Johannes Leimer    schedule 13.01.2015