mirror of
https://gitee.com/lab1024/smart-admin.git
synced 2025-12-28 02:16:02 +08:00
优化:使用更加安全的编码保存用户密码
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
<java.version>1.8</java.version>
|
||||
<springboot.version>2.7.18</springboot.version>
|
||||
<spring-mock.version>2.0.8</spring-mock.version>
|
||||
<spring-security-crypto.version>6.4.3</spring-security-crypto.version>
|
||||
<mybatis-plus.version>3.5.2</mybatis-plus.version>
|
||||
<mysql-connector-j.version>8.0.33</mysql-connector-j.version>
|
||||
<p6spy.version>3.9.1</p6spy.version>
|
||||
@@ -50,7 +51,7 @@
|
||||
<velocity-tools.version>3.1</velocity-tools.version>
|
||||
<sa-token.version>1.37.0</sa-token.version>
|
||||
<ip2region.version>2.7.0</ip2region.version>
|
||||
<bcprov.version>1.59</bcprov.version>
|
||||
<bcprov.version>1.80</bcprov.version>
|
||||
<jackson-datatype-jsr310.version>2.13.4</jackson-datatype-jsr310.version>
|
||||
<jackson-dataformat-yaml.version>2.16.1</jackson-dataformat-yaml.version>
|
||||
<smartdb.version>1.2.0</smartdb.version>
|
||||
@@ -85,6 +86,12 @@
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-crypto</artifactId>
|
||||
<version>${spring-security-crypto.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
@@ -261,7 +268,7 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15on</artifactId>
|
||||
<artifactId>bcprov-jdk18on</artifactId>
|
||||
<version>${bcprov.version}</version>
|
||||
</dependency>
|
||||
|
||||
@@ -451,4 +458,4 @@
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
||||
@@ -297,38 +297,39 @@ public class EmployeeService {
|
||||
if (employeeEntity == null) {
|
||||
return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST);
|
||||
}
|
||||
|
||||
// 校验原始密码
|
||||
String oldPassword = SecurityPasswordService.getEncryptPwd(updatePasswordForm.getOldPassword());
|
||||
if (!Objects.equals(oldPassword, employeeEntity.getLoginPwd())) {
|
||||
if (!SecurityPasswordService.matchesPwd(updatePasswordForm.getOldPassword(),employeeEntity.getLoginPwd()) ) {
|
||||
return ResponseDTO.userErrorParam("原密码有误,请重新输入");
|
||||
}
|
||||
|
||||
// 新旧密码相同
|
||||
if (Objects.equals(updatePasswordForm.getOldPassword(), updatePasswordForm.getNewPassword()) ){
|
||||
return ResponseDTO.userErrorParam("新密码与原始密码相同,请重新输入");
|
||||
}
|
||||
|
||||
// 校验密码复杂度
|
||||
ResponseDTO<String> validatePassComplexity = securityPasswordService.validatePasswordComplexity(updatePasswordForm.getNewPassword());
|
||||
if (!validatePassComplexity.getOk()) {
|
||||
return validatePassComplexity;
|
||||
}
|
||||
|
||||
// 新旧密码相同
|
||||
String newPassword = SecurityPasswordService.getEncryptPwd(updatePasswordForm.getNewPassword());
|
||||
if (Objects.equals(oldPassword, newPassword)) {
|
||||
return ResponseDTO.userErrorParam("新密码与原始密码相同,请重新输入");
|
||||
}
|
||||
|
||||
// 根据三级等保规则,校验密码是否重复
|
||||
ResponseDTO<String> passwordRepeatTimes = securityPasswordService.validatePasswordRepeatTimes(requestUser, updatePasswordForm.getNewPassword());
|
||||
if (!passwordRepeatTimes.getOk()) {
|
||||
return ResponseDTO.error(passwordRepeatTimes);
|
||||
}
|
||||
|
||||
|
||||
// 更新密码
|
||||
String newEncryptPassword = SecurityPasswordService.getEncryptPwd(updatePasswordForm.getNewPassword());
|
||||
EmployeeEntity updateEntity = new EmployeeEntity();
|
||||
updateEntity.setEmployeeId(employeeId);
|
||||
updateEntity.setLoginPwd(newPassword);
|
||||
updateEntity.setLoginPwd(newEncryptPassword);
|
||||
employeeDao.updateById(updateEntity);
|
||||
|
||||
// 保存修改密码密码记录
|
||||
securityPasswordService.saveUserChangePasswordLog(requestUser, newPassword, oldPassword);
|
||||
securityPasswordService.saveUserChangePasswordLog(requestUser, newEncryptPassword, employeeEntity.getLoginPwd());
|
||||
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
@@ -208,7 +208,7 @@ public class LoginService implements StpInterface {
|
||||
}
|
||||
|
||||
// 密码错误
|
||||
if (!employeeEntity.getLoginPwd().equals(SecurityPasswordService.getEncryptPwd(requestPassword))) {
|
||||
if ( !SecurityPasswordService.matchesPwd(requestPassword,employeeEntity.getLoginPwd()) ) {
|
||||
// 记录登录失败
|
||||
saveLoginLog(employeeEntity, ip, userAgent, "密码错误", LoginLogResultEnum.LOGIN_FAIL);
|
||||
// 记录等级保护次数
|
||||
|
||||
@@ -87,6 +87,11 @@
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-crypto</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
@@ -225,7 +230,7 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15on</artifactId>
|
||||
<artifactId>bcprov-jdk18on</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -302,4 +307,4 @@
|
||||
</dependencies>
|
||||
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
||||
@@ -5,8 +5,8 @@ import net.lab1024.sa.base.common.domain.ResponseDTO;
|
||||
import net.lab1024.sa.base.common.util.SmartStringUtil;
|
||||
import net.lab1024.sa.base.module.support.securityprotect.dao.PasswordLogDao;
|
||||
import net.lab1024.sa.base.module.support.securityprotect.domain.PasswordLogEntity;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.springframework.security.crypto.argon2.Argon2PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
@@ -46,6 +46,8 @@ public class SecurityPasswordService {
|
||||
@Resource
|
||||
private Level3ProtectConfigService level3ProtectConfigService;
|
||||
|
||||
static Argon2PasswordEncoder encoder = Argon2PasswordEncoder.defaultsForSpringSecurity_v5_8();
|
||||
|
||||
/**
|
||||
* 校验密码复杂度
|
||||
*/
|
||||
@@ -84,8 +86,9 @@ public class SecurityPasswordService {
|
||||
|
||||
// 检查最近几次是否有重复密码
|
||||
List<String> oldPasswords = passwordLogDao.selectOldPassword(requestUser.getUserType().getValue(), requestUser.getUserId(), level3ProtectConfigService.getRegularChangePasswordNotAllowRepeatTimes());
|
||||
if (oldPasswords != null && oldPasswords.contains(getEncryptPwd(newPassword))) {
|
||||
return ResponseDTO.userErrorParam(String.format("与前%s个历史密码重复,请换个密码!", level3ProtectConfigService.getRegularChangePasswordNotAllowRepeatTimes()));
|
||||
boolean isDuplicate = oldPasswords.stream().anyMatch(oldPassword -> encoder.matches(newPassword, oldPassword));
|
||||
if (isDuplicate) {
|
||||
return ResponseDTO.userErrorParam(String.format("与前%d个历史密码重复,请换个密码!", level3ProtectConfigService.getRegularChangePasswordNotAllowRepeatTimes()));
|
||||
}
|
||||
|
||||
return ResponseDTO.ok();
|
||||
@@ -143,7 +146,14 @@ public class SecurityPasswordService {
|
||||
* 获取 加密后 的密码
|
||||
*/
|
||||
public static String getEncryptPwd(String password) {
|
||||
return DigestUtils.md5Hex(String.format(PASSWORD_SALT_FORMAT, password));
|
||||
return encoder.encode(password);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验密码是否匹配
|
||||
*/
|
||||
public static Boolean matchesPwd( String password, String encodedPassword){
|
||||
return encoder.matches( password, encodedPassword);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user