在Spring Security 5中如何使用默认的Password Encoder

2023-03-07 16:17:53 浏览数 (1)

原文链接:https://www.baeldung.com/spring-security-5-default-password-encoder

作者: baeldung

译者: helloworldtang

1. 概览

在Spring Security 4中,可以使用in-memory认证模式直接将密码以纯文本的形式存储。

在Spring Security 5中,密码管理机制进行了一次大的修改,默认引入了更安全的加/解密机制。这意味着,如果您的Spring应用程序使用纯文本的方式存储密码,升级到Spring Security 5后可能会出现问题。

在这个简短的教程中,我们将描述其中一个潜在的问题,并演示如何解决。

2. Spring Security 4

我们将给出一个常规的安全配置,它使用了简单的in-memory认证模式(适用于Spring 4):

代码语言:javascript复制
@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使用相同的配置,将会报错:

代码语言:javascript复制
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"

这个错误告诉我们,给定的密码 不能被解码,这是因为我们的in-memory认证模式没有配置Password Encoder 。

3. Spring Security 5

我们可以通过使用PasswordEncoderFactories类创建一个DelegatingPasswordEncoder的方式来解决这个问题。

我们使用这个Password Encoder来配置我们的用户信息:

代码语言:javascript复制
@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 Password Encoder。内存中存储密码的格式如下所示:

代码语言:javascript复制
{bcrypt}$2a$10$MF7hYnWLeLT66gNccBgxaONZHbrSMjlUofkp50sSpBw2PJjUqU.zS

虽然我们可以实现自定义的Password Encoder,但建议使用PasswordEncoderFactories类提供的默认编码器。

3.1. 迁移现有的密码

我们可以通过以下方式将现有密码升级到推荐的Spring Security 5标准:

  • 用BCryptPasswordEncoder加密后的密码更新老密码:
代码语言:javascript复制
String encoded = new BCryptPasswordEncoder().encode(plainTextPassword);
  • 在加密后的密码前添加Password Encoder各自的标识符
代码语言:javascript复制
{bcrypt}$2a$10$MF7hYnWLeLT66gNccBgxaONZHbrSMjlUofkp50sSpBw2PJjUqU.zS
{sha256}97cde38028ad898ebc02e690819fa220e88c62e0699403e94fff291cfffaf8410849f27605abcbc0
  • 当存储密码的Password Encoder未知时,提示用户更新他们的密码

4. 总结

在这个简短的例子中,我们使用新的密码存储机制将一个Spring 4下的,使用了in-memory 认证模式的配置升级到了Spring 5。

与往常一样,您可以在GitHub上查看源代码。

0 人点赞