Кодировщик паролей по умолчанию в Spring Security 5

Кодировщик паролей по умолчанию в 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.