Подтвердить что ты не робот

Как использовать новый PasswordEncoder из Spring Безопасность

Как и в случае с Spring Security 3.1.4.RELEASE, старый org.springframework.security.authentication.encoding.PasswordEncoder устарел в пользу org.springframework.security.crypto.password.PasswordEncoder. Поскольку мое приложение еще не было выпущено для публики, я решил перейти к новому, а не устаревшему API.

До сих пор у меня был ReflectionSaltSource, который автоматически использовал дату регистрации пользователя как пароль пользователя для пароля.

String encodedPassword = passwordEncoder.encodePassword(rawPassword, saltSource.getSalt(user));

В процессе входа в систему Spring также использовал мой beans, чтобы проверить, может ли пользователь войти или не может войти. Я не могу этого добиться в новом кодовом коде, поскольку стандартная реализация SHA-1 - StandardPasswordEncoder имеет возможность добавлять глобальную секретную соль во время создания кодировщика.

Есть ли какой-либо разумный способ настройки с помощью не устаревшего API?

4b9b3361

Ответ 1

Если вы на самом деле не зарегистрировали ни одного пользователя с существующим форматом, тогда лучше было бы переключиться на использование кодировщика паролей BCrypt.

Это намного меньше хлопот, так как вам не нужно беспокоиться о соли вообще - детали полностью инкапсулированы в кодере. Использование BCrypt сильнее, чем использование простого алгоритма хэширования, а также стандарт, совместимый с приложениями, использующими другие языки.

На самом деле нет причин выбирать какие-либо другие параметры для нового приложения.

Ответ 2

Вот реализация BCrypt, которая работает для меня.

в spring -security.xml

<authentication-manager >
    <authentication-provider ref="authProvider"></authentication-provider>  
    </authentication-manager>
<beans:bean id="authProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
  <beans:property name="userDetailsService" ref="userDetailsServiceImpl" />
  <beans:property name="passwordEncoder" ref="encoder" />
</beans:bean>
<!-- For hashing and salting user passwords -->
    <beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>

В классе java

PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String hashedPassword = passwordEncoder.encode(yourpassword);

Для более подробного примера spring безопасности Нажмите здесь

Надеюсь, это поможет.

Спасибо

Ответ 3

У меня была аналогичная проблема. Мне нужно было сохранить устаревшие зашифрованные пароли (Base64/SHA-1/Random salt Encoded), так как пользователи не захотят менять свои пароли или перерегистрировать. Однако я также хотел использовать кодировщик BCrypt.

Мое решение состояло в том, чтобы написать декодер, сделанный на заказ, который проверяет, какой метод шифрования был использован перед сопоставлением (в скопированных с помощью $).

Чтобы обойти проблему солей, я передаю в декодер конкатенированную строку соли + зашифрованный пароль через мой измененный объект пользователя.

Декодер

@Component
public class LegacyEncoder implements PasswordEncoder {

    private static final String BCRYP_TYPE = "$";
    private static final PasswordEncoder BCRYPT = new BCryptPasswordEncoder();

    @Override
    public String encode(CharSequence rawPassword) {

    return BCRYPT.encode(rawPassword);
    }

    @Override
    public boolean matches(CharSequence rawPassword, String encodedPassword) {

    if (encodedPassword.startsWith(BCRYP_TYPE)) {
        return BCRYPT.matches(rawPassword, encodedPassword);
    }

    return sha1SaltMatch(rawPassword, encodedPassword);
    }

    @SneakyThrows
    private boolean sha1SaltMatch(CharSequence rawPassword, String encodedPassword) {

    String[] saltHash = encodedPassword.split(User.SPLIT_CHAR);

    // Legacy code from old system   
    byte[] b64salt = Base64.getDecoder().decode(saltHash[0].getBytes());
    byte[] validHash = Base64.getDecoder().decode(saltHash[1]);
    byte[] checkHash = Utility.getHash(5, rawPassword.toString(), b64salt);

    return Arrays.equals(checkHash, validHash);
    }

}

Пользовательский объект

public class User implements UserDetails {

    public static final String SPLIT_CHAR = ":";

    @Id
    @Column(name = "user_id", nullable = false)
    private Integer userId;

    @Column(nullable = false, length = 60)
    private String password;

    @Column(nullable = true, length = 32)
    private String salt;

.
.

    @PostLoad
    private void init() {

    username = emailAddress; //To comply with UserDetails
    password = salt == null ? password : salt + SPLIT_CHAR + password;
    }        

Вы также можете добавить крючок для повторного кодирования пароля в новом формате BCrypt и заменить его. Таким образом, поэтапный отказ от старого метода.

Ответ 4

Только что обошел Интернет, чтобы узнать об этом и о вариантах в Spring, я бы ответил на второй вопрос Luke, используйте BCrypt (он упоминается в исходный код в Spring).

Лучший ресурс, который я нашел, чтобы объяснить, почему хеш/соль и почему использовать BCrypt, является хорошим выбором здесь: Соленый пароль Хеширование - Выполнение этого права.