📄 认证中心扩展兼容已有系统密码
内部资料,请扫码登录
pigcloud
# PIG 默认密码加解密策略
PIG 默认采用的密码加密方式是 Bcrypt 加密且不可逆。既只能通过用户输入的明文加密后和数据库存储的密文对比确定是否正确,而数据库存储的密文无法解密。
# Bcrypt 四个变量解析
- saltRounds: 正数,代表 hash 杂凑次数,数值越高越安全,默认 10 次。
- myPassword: 明文密码字符串。
- salt: 盐,一个 128bits 随机字符串,22 字符。 (直接内置了,所以库表的 salt 是空的)
- myHash: 经过明文密码 password 和盐 salt 进行 hash,个人的理解是默认 10 次下 ,循环加盐 hash10 次,得到 myHash
# 业务需求
目前登录系统的用户复用来自 已有系统的用户表 用户和密码,密码加解密过程需要自定义。
原有密码存储是 MD5(明文+自定义盐)
# ① 增加自定义密码加解密
- 代码示例: 这里使用 MD5 加自定义盐的形式
public class CustomPasswordEncoder implements PasswordEncoder {
public static final String SPLIT_FLAG = "{SPLIT_FLAG}";
/**
* 密码加密过程
*
* @param rawPassword 原文
* @return 密码
*/
@Override
public String encode(CharSequence rawPassword) {
// 使用MD5 加密
return SecureUtil.md5(rawPassword.toString());
}
/**
* spring security 密码匹配过程
*
* @param rawPassword 用户输入的原文
* @param encodedPassword 数据库存储的密文 + {SPLIT_FLAG} + 随机盐
* @return true/false
*/
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
// 1. 获取用户密文 和 用户对应的salt
List<String> strings = StrUtil.split(encodedPassword, SPLIT_FLAG);
String dbEncoded = strings.get(0);
String salt = strings.get(1);;
// 2. 使用输入的明文+随机盐 继续加密
String inputEncode = encode(rawPassword + salt);
// 3. 比较加密结果和数据库存储的密文是否一致
return dbEncoded.equals(inputEncode);
}
/**
* 获取支持自定义加密和原生加密的扩展实例
*
* @return PasswordEncoder
*/
public static PasswordEncoder getInstance() {
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());
// 注意这个标识和下文 {pig} 保持一致,这个就是自定义解析器的别名
encoders.put("pig", new CustomPasswordEncoder());
return new DelegatingPasswordEncoder(encodingId, encoders);
}
}
# ② 配置 PasswordEncoder
# ③ 修改核心认证代码
# ④ 传递原有的 salt 字段
# 重新编译代码,清空缓存 redis 重新登录即可。
mvn clean install