Кодировщик паролей по умолчанию в Spring Security 5
1. обзор
В Spring Security 4 можно было хранить пароли в виде простого текста с использованием аутентификации в памяти.
Капитальный пересмотр процесса управления паролями в версии 5 представил более безопасный механизм по умолчанию для кодирования и декодирования паролей. Это означает, что если ваше приложение Spring хранит пароли в виде простого текста, обновление до Spring Security 5 может вызвать проблемы.
В этом коротком руководстве мы опишем одну из этих потенциальных проблем и продемонстрируем решение проблемы.
2. Spring Security 4
Мы начнем с демонстрации стандартной конфигурации безопасности, которая обеспечивает простую аутентификацию в памяти (действительна для Spring 4):
@Configuration
public class InMemoryAuthWebSecurityConfigurer
extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication()
.withUser("spring")
.password("secret")
.roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/private/**")
.authenticated()
.antMatchers("/public/**")
.permitAll()
.and()
.httpBasic();
}
}
Эта конфигурация определяет аутентификацию для всех сопоставленных методов/private/ и общий доступ для всего, что находится под/public/..
Если мы будем использовать ту же конфигурацию в Spring Security 5, мы получим следующую ошибку:
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
Ошибка сообщает нам, что данный парольcouldn’t be decoded since no password encoder was configured for our in-memory authentication.
3. Spring Security 5
Мы можем исправить эту ошибку, определивDelegatingPasswordEncoder w с классомPasswordEncoderFactories.
Мы используем этот кодировщик, чтобы настроить нашего пользователя наAuthenticationManagerBuilder:
@Configuration
public class InMemoryAuthWebSecurityConfigurer
extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
auth.inMemoryAuthentication()
.withUser("spring")
.password(encoder.encode("secret"))
.roles("USER");
}
}
Теперь с этой конфигурацией мы сохраняем наш пароль в памяти с помощью BCrypt в следующем формате:
{bcrypt}$2a$10$MF7hYnWLeLT66gNccBgxaONZHbrSMjlUofkp50sSpBw2PJjUqU.zS
Хотя мы можем определить собственный набор кодировщиков паролей, рекомендуется придерживатьсяdefault encoders, предоставленного вPasswordEncoderFactories.
3.1. Перенос существующих паролей
Мы можем обновить существующие пароли до рекомендуемых стандартов Spring Security 5:
-
Обновление сохраненных паролей в виде простого текста с их кодированным значением:
String encoded = new BCryptPasswordEncoder().encode(plainTextPassword);
-
Префикс хеширует сохраненные пароли с их известным идентификатором кодировщика:
{bcrypt}$2a$10$MF7hYnWLeLT66gNccBgxaONZHbrSMjlUofkp50sSpBw2PJjUqU.zS
{sha256}97cde38028ad898ebc02e690819fa220e88c62e0699403e94fff291cfffaf8410849f27605abcbc0
-
Запрос пользователей обновить свои пароли, когда механизм кодирования для сохраненных паролей неизвестен
4. Заключение
В этом быстром примере мы обновили действительную конфигурацию аутентификации Spring 4 в памяти до Spring 5, используя новый механизм хранения паролей.
Как всегда, вы можете найти исходный код наGitHub project.