PasswordEncoder 使用 DelegatingPasswordEncoder, 方便未来切换密码加密算法

This commit is contained in:
b2baccline
2021-07-10 17:11:15 +08:00
parent 9e3424118e
commit 1a58c677e9
2 changed files with 69 additions and 15 deletions

View File

@@ -4,10 +4,17 @@ import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.symmetric.AES;
import org.springframework.security.crypto.argon2.Argon2PasswordEncoder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
/**
* 前后端交互中密码使用 AES 加密,模式: CBCpadding: PKCS5偏移量暂不定制和密钥相同。 <br/>
@@ -22,7 +29,36 @@ public final class PasswordUtils {
private PasswordUtils() {
}
public static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();
/**
* 创建一个密码加密的代理,方便后续切换密码的加密算法
* @see PasswordEncoderFactories#createDelegatingPasswordEncoder()
* @return DelegatingPasswordEncoder
*/
@SuppressWarnings("deprecation")
private static PasswordEncoder createDelegatingPasswordEncoder() {
String encodingId = "bcrypt";
Map<String, PasswordEncoder> encoders = new HashMap<>(10);
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
encoders.put(encodingId, bCryptPasswordEncoder);
encoders.put("ldap", new org.springframework.security.crypto.password.LdapShaPasswordEncoder());
encoders.put("MD4", new org.springframework.security.crypto.password.Md4PasswordEncoder());
encoders.put("MD5", new org.springframework.security.crypto.password.MessageDigestPasswordEncoder("MD5"));
encoders.put("noop", org.springframework.security.crypto.password.NoOpPasswordEncoder.getInstance());
encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
encoders.put("scrypt", new SCryptPasswordEncoder());
encoders.put("SHA-1", new org.springframework.security.crypto.password.MessageDigestPasswordEncoder("SHA-1"));
encoders.put("SHA-256",
new org.springframework.security.crypto.password.MessageDigestPasswordEncoder("SHA-256"));
encoders.put("sha256", new org.springframework.security.crypto.password.StandardPasswordEncoder());
encoders.put("argon2", new Argon2PasswordEncoder());
DelegatingPasswordEncoder delegatingPasswordEncoder = new DelegatingPasswordEncoder(encodingId, encoders);
// 设置默认的密码解析器,以便兼容历史版本的密码
delegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(bCryptPasswordEncoder);
return delegatingPasswordEncoder;
}
public static final PasswordEncoder ENCODER = PasswordUtils.createDelegatingPasswordEncoder();
/**
* 将前端传递过来的密文解密为明文
@@ -51,12 +87,30 @@ public final class PasswordUtils {
}
/**
* 使用BCrypt加密密码
* @param password 明文密码
* @return BCrypt加密后的密码
* 加密密码
* @param rawPassword 明文密码
* @return 密文密码
*/
public static String encodeBCrypt(String password) {
return ENCODER.encode(password);
public static String encode(CharSequence rawPassword) {
return ENCODER.encode(rawPassword);
}
/**
* 判断明文密码和密文密码是否匹配
* @param rawPassword 明文密码
* @param encodedPassword 密文密码
* @return 匹配返回 true
*/
public static boolean matches(CharSequence rawPassword, String encodedPassword) {
return ENCODER.matches(rawPassword, encodedPassword);
}
/**
* 判断是否需要升级加密算法
* @param encodedPassword 密文密码
* @return 需要返回 true
*/
public static boolean upgradeEncoding(String encodedPassword) {
return ENCODER.upgradeEncoding(encodedPassword);
}
}

View File

@@ -138,10 +138,10 @@ public class SysUserServiceImpl extends ExtendServiceImpl<SysUserMapper, SysUser
SysUser sysUser = SysUserConverter.INSTANCE.dtoToPo(sysUserDto);
sysUser.setStatus(SysUserConst.Status.NORMAL.getValue());
sysUser.setType(SysUserConst.Type.SYSTEM.getValue());
// 对密码进行 BCrypt 加密
String password = sysUserDto.getPassword();
String bCryptPassword = PasswordUtils.encodeBCrypt(password);
sysUser.setPassword(bCryptPassword);
// 对密码进行加密
String rawPassword = sysUserDto.getPassword();
String encodedPassword = PasswordUtils.encode(rawPassword);
sysUser.setPassword(encodedPassword);
// 保存用户
boolean insertSuccess = SqlHelper.retBool(baseMapper.insert(sysUser));
@@ -208,15 +208,15 @@ public class SysUserServiceImpl extends ExtendServiceImpl<SysUserMapper, SysUser
/**
* 修改用户密码
* @param userId 用户ID
* @param password 明文密码
* @param rawPassword 明文密码
* @return 更新成功true
*/
@Override
public boolean updatePassword(Integer userId, String password) {
public boolean updatePassword(Integer userId, String rawPassword) {
Assert.isTrue(adminUserChecker.hasModifyPermission(getById(userId)), "当前用户不允许修改!");
// BCrypt 加密
String bCryptPassword = PasswordUtils.encodeBCrypt(password);
return baseMapper.updatePassword(userId, bCryptPassword);
// 密码加密加密
String encodedPassword = PasswordUtils.encode(rawPassword);
return baseMapper.updatePassword(userId, encodedPassword);
}
/**