Spring Securty - как разделить bcrypt между двумя приложениями?

У меня есть приложение REST api, в котором учетные данные хранятся в виде хэшей в таблице базы данных. Кроме того, у меня есть другое приложение, которое управляет учетными данными для первого приложения. Я создал в обоих приложениях DelagtingPasswordEncoder.

@Bean
public PasswordEncoder delegatingPasswordEncoder() {
    PasswordEncoder defaultEncoder = NoOpPasswordEncoder.getInstance();
    Map<String, PasswordEncoder> encoders = new HashMap<>();
    encoders.put("bcrypt", new BCryptPasswordEncoder());
    encoders.put("scrypt", new SCryptPasswordEncoder());

    DelegatingPasswordEncoder passworEncoder = new DelegatingPasswordEncoder("bcrypt", encoders);
    passworEncoder.setDefaultPasswordEncoderForMatches(defaultEncoder);

    return passworEncoder;
}

Когда я пытаюсь выполнить аутентификацию на REST api с учетными данными, сгенерированными административным приложением, я получаю Unauthorized 401. Хэш bcrypt, сгенерированный в приложении администратора, не может быть сопоставлен bcrypt приложения REST api. Я предполагаю, что случайная соль, сгенерированная bcrypt, также зависит от контекста, в котором она инициализирована?

Мы использовали базовую аутентификацию для теста с правильным паролем, сгенерированным приложением администрирования перед сохранением его в виде хэша в базе данных.

Оба приложения используют одну и ту же базу данных, но в остальном независимы друг от друга.

Можно ли использовать bcrypt в обоих приложениях или как лучше всего обмениваться паролями между обоими приложениями?

Моя реализация была неправильной. Теперь я просто создаю независимый BcryptPasswordEncoder и сохраняю пароль в приложении ADMIN, и приложение API может сопоставить его. Так что все работает как положено

Marc 22.10.2018 16:49
0
1
298
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам не нужно совместно использовать кодировщик BCrypt между приложениями.

Структура хэша BCryptPasswordEncoder представляет собой конкатенацию:

  • алгоритм хеширования
  • количество итераций хеширования
  • поваренная соль
  • хешированная соль + пароль

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

Обратите внимание, что алгоритм хеширования, количество итераций и извлечение соли выполняются негласно методом matches из BCryptPasswordEncoder (который принимает в качестве аргументов хешированный пароль и простой пароль).

Я предполагаю, что вы не используете метод matches из BCryptPasswordEncoder для сравнения пароля запроса с паролем БД, а повторно хешируете пароль запроса и сравниваете полученный хэш с хешем базы данных. Это не сработает, поскольку закодированный метод сгенерирует новую соль, с помощью которой будет хешировать пароль, что приведет к другим хешам.

У меня есть способ хеширования паролей в открытом виде при первой аутентификации. У меня есть это для миграции. Мы помещаем пароли в виде открытого текста в базу данных, и при первом запросе аутентификации они хешируются, и хешированное значение сохраняется. Затем проверяется только хешированное значение с помощью метода совпадений. Это отлично работает в приложении REST. Только для хэшей, сгенерированных приложением администрирования, не работает. В обоих приложениях я генерирую компонент DelegatingPasswordEncoder, который автоматически подключается к службам для генерации хэша посредством кодирования.

Marc 19.10.2018 15:54

Так не важно, что в разных приложениях есть разные бины? В любом случае хеш bcrypt должен быть проверен с помощью метода совпадений?

Marc 19.10.2018 15:54

Да, BCrypt - это детерминированный алгоритм. При одном и том же вводе он всегда будет генерировать один и тот же вывод.

user10367961 19.10.2018 15:55

Другие вопросы по теме