作者: 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加密后的密码更新老密码:
String encoded = new BCryptPasswordEncoder().encode(plainTextPassword);
- 在加密后的密码前添加Password Encoder各自的标识符
{bcrypt}$2a$10$MF7hYnWLeLT66gNccBgxaONZHbrSMjlUofkp50sSpBw2PJjUqU.zS
{sha256}97cde38028ad898ebc02e690819fa220e88c62e0699403e94fff291cfffaf8410849f27605abcbc0
- 当存储密码的Password Encoder未知时,提示用户更新他们的密码
4. 总结
在这个简短的例子中,我们使用新的密码存储机制将一个Spring 4下的,使用了in-memory 认证模式的配置升级到了Spring 5。
与往常一样,您可以在GitHub上查看源代码。