密码加密
Spring Security 内置了加密机制
只需要实现PasswordEncoder接口即可
接入BCrypt加密
自定义自己的加密类继承BCryptPasswordEncoder
package com.yang.springsecurity.provider;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;
import java.util.regex.Pattern;
@Component
public class MyPasswordEncoder extends BCryptPasswordEncoder {
private Pattern BCRYPT_PATTERN = Pattern
.compile("\\A\\$2(a|y|b)?\\$(\\d\\d)\\$[./0-9A-Za-z]{53}");
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
//判断系统之前的用户是否是采用bcrypt加密,不是的就采用明文匹配
if (!BCRYPT_PATTERN.matcher(encodedPassword).matches()){
return rawPassword.toString().matches(encodedPassword);
}
return super.matches(rawPassword, encodedPassword);
}
}
修改配置应用自己的加密
@Autowired
private MyPasswordEncoder myPasswordEncoder;
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
//添加AuthenticationProvider
auth.userDetailsService(myUserDetailsService).passwordEncoder(myPasswordEncoder);
}
注意:
新系统引入密码加密,只需指定明确加密方式即可。
但如果老系统使用明文或者其它加密方式,现在要引入bcrypt加密方式可采用以下几种方式
-
兼容
重新matches()方法,判断系统之前的用户是否是采用bcrypt加密,不是的就采用明文匹配
-
增量更新
判断系统之前的用户是否是采用bcrypt加密,不是的就采用明文匹配,则尝试使用用户输入的密码重新生成BCrypt密文,并写回数据库。
以旧的加密方案作为基础接入BCrypt加密。
例如,旧的方案是MD5加密,即数据库中的所有
密码都是 MD5形式的密码,那么直接把这些密码当作明文,先“跑库”生成 BCrypt 密文,再使用
encode 和 matches 两个方法在执行 BCrypt 加密之前都先用MD5运算一遍即可。
SpringSecurity5.x 加密方式采用{Id}password
的格式配置,这样做迁移的时候系统可以兼容多种加密方式。
我们可以看一下PasswordEncoderFactories自带的加密方式
public class PasswordEncoderFactories {
public static PasswordEncoder createDelegatingPasswordEncoder() {
String encodingId = "bcrypt";
Map<String, PasswordEncoder> encoders = new HashMap();
encoders.put(encodingId, new BCryptPasswordEncoder());
encoders.put("ldap", new LdapShaPasswordEncoder());
encoders.put("MD4", new Md4PasswordEncoder());
encoders.put("MD5", new MessageDigestPasswordEncoder("MD5"));
encoders.put("noop", NoOpPasswordEncoder.getInstance());
encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
encoders.put("scrypt", new SCryptPasswordEncoder());
encoders.put("SHA-1", new MessageDigestPasswordEncoder("SHA-1"));
encoders.put("SHA-256", new MessageDigestPasswordEncoder("SHA-256"));
encoders.put("sha256", new StandardPasswordEncoder());
encoders.put("argon2", new Argon2PasswordEncoder());
return new DelegatingPasswordEncoder(encodingId, encoders);
}
private PasswordEncoderFactories() {
}
}