错误解释
请点击查看=> 问题和解决的官方文档 (本文主要是翻译和部分解释)
In Spring Security 4, it was possible to store passwords in plain text using in-memory authentication.
A major overhaul of the password management process in version 5 has introduced more secure default mechanism for encoding and decoding passwords. This means that if your Spring application stores passwords in plain text, upgrading to Spring Security 5 may cause problems.
In this short tutorial, we’ll describe one of those potential problems and demonstrate a solution to the issue.
即对于Spring Security 4, 支持使用明文密码(比如内存中的账号密码)。但是在Spring Security 5后都必须是用加密的密文。不然报错。
以下是Spring Security 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();
}
}
如果在 Spring Security 5还是这样写。必然报错如下
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
官方解释:没有为内存身份认证配置加密方法。因为Spring Security 5对安全规范更严格了。
解决方案
直接上代码
@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");
}
}
密文shadow格式类似:
{bcrypt}$2a MF7hYnWLeLT66gNccBgxaONZHbrSMjlUofkp50sSpBw2PJjUqU.zS
也可以new 该对象:
String encoded = new BCryptPasswordEncoder().encode(plainTextPassword);
推荐
Although we can define our own set of password encoders, it’s recommended to stick with the default encoders provided in PasswordEncoderFactories.
推荐使用这个由PasswordEncoderFactories默认提供的加密编码器,即便可以自定义使用其他的。
注意
// 1
PasswordEncoder encoder1 = PasswordEncoderFactories.createDelegatingPasswordEncoder();
// 2
PasswordEncoder encoder2 = new BCryptPasswordEncoder();
// s1 和 s2 长度格式都不一样
String s1 = encoder1.encode("mima");
String s2 = encoder2.encode("mima");
encode1在内存账号认证加密可以。
但是对于数据库,实现UserDetailService的只能用encode2,不然显示
That is not like BCrypt