mirror of
https://github.com/continew-org/continew-admin.git
synced 2025-09-09 20:57:21 +08:00
refactor: 使用枚举方法优化部分密码策略校验
This commit is contained in:
@@ -16,9 +16,16 @@
|
||||
|
||||
package top.continew.admin.system.enums;
|
||||
|
||||
import cn.hutool.core.util.ReUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import top.continew.admin.common.constant.RegexConstants;
|
||||
import top.continew.admin.common.constant.SysConstants;
|
||||
import top.continew.admin.system.model.entity.UserDO;
|
||||
import top.continew.admin.system.service.UserPasswordHistoryService;
|
||||
import top.continew.starter.core.util.validate.ValidationUtils;
|
||||
|
||||
/**
|
||||
* 密码策略枚举
|
||||
@@ -31,47 +38,110 @@ import top.continew.admin.common.constant.SysConstants;
|
||||
@RequiredArgsConstructor
|
||||
public enum PasswordPolicyEnum {
|
||||
|
||||
/**
|
||||
* 登录密码错误锁定账号的次数
|
||||
*/
|
||||
PASSWORD_ERROR_LOCK_COUNT(null, SysConstants.NO, 10),
|
||||
|
||||
/**
|
||||
* 登录密码错误锁定账号的时间(min)
|
||||
*/
|
||||
PASSWORD_ERROR_LOCK_MINUTES(null, 1, 1440),
|
||||
|
||||
/**
|
||||
* 密码到期提前提示(天)
|
||||
*/
|
||||
PASSWORD_EXPIRATION_WARNING_DAYS(null, SysConstants.NO, Integer.MAX_VALUE),
|
||||
|
||||
/**
|
||||
* 密码有效期(天)
|
||||
*/
|
||||
PASSWORD_EXPIRATION_DAYS(null, SysConstants.NO, 999),
|
||||
|
||||
/**
|
||||
* 密码重复使用规则
|
||||
*/
|
||||
PASSWORD_REUSE_POLICY("不允许使用最近 %s 次的历史密码", 3, 32),
|
||||
|
||||
/**
|
||||
* 密码最小长度
|
||||
*/
|
||||
PASSWORD_MIN_LENGTH("密码最小长度为 %s 个字符", 8, 32),
|
||||
|
||||
/**
|
||||
* 密码是否允许包含正反序账号名
|
||||
*/
|
||||
PASSWORD_ALLOW_CONTAIN_USERNAME("密码不允许包含正反序账号名", SysConstants.NO, SysConstants.YES),
|
||||
PASSWORD_MIN_LENGTH("密码最小长度为 %s 个字符", 8, 32) {
|
||||
@Override
|
||||
public void validate(String password, int policyValue, UserDO user) {
|
||||
// 最小长度校验
|
||||
ValidationUtils.throwIf(StrUtil.length(password) < policyValue, this.getDescription()
|
||||
.formatted(policyValue));
|
||||
// 完整校验
|
||||
int passwordMaxLength = this.getMax();
|
||||
ValidationUtils.throwIf(!ReUtil.isMatch(RegexConstants.PASSWORD_TEMPLATE
|
||||
.formatted(policyValue, passwordMaxLength), password), "密码长度为 {}-{} 个字符,支持大小写字母、数字、特殊字符,至少包含字母和数字", policyValue, passwordMaxLength);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 密码是否必须包含特殊字符
|
||||
*/
|
||||
PASSWORD_CONTAIN_SPECIAL_CHARACTERS("密码必须包含特殊字符", SysConstants.NO, SysConstants.YES),;
|
||||
PASSWORD_CONTAIN_SPECIAL_CHARACTERS("密码必须包含特殊字符", SysConstants.NO, SysConstants.YES) {
|
||||
@Override
|
||||
public void validate(String password, int policyValue, UserDO user) {
|
||||
ValidationUtils.throwIf(policyValue == SysConstants.YES && !ReUtil
|
||||
.isMatch(RegexConstants.SPECIAL_CHARACTER, password), this.getDescription());
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 密码是否允许包含正反序账号名
|
||||
*/
|
||||
PASSWORD_ALLOW_CONTAIN_USERNAME("密码不允许包含正反序账号名", SysConstants.NO, SysConstants.YES) {
|
||||
@Override
|
||||
public void validate(String password, int policyValue, UserDO user) {
|
||||
if (policyValue <= SysConstants.NO) {
|
||||
String username = user.getUsername();
|
||||
ValidationUtils.throwIf(StrUtil.containsAnyIgnoreCase(password, username, StrUtil
|
||||
.reverse(username)), this.getDescription());
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 密码重复使用规则
|
||||
*/
|
||||
PASSWORD_REUSE_POLICY("不允许使用最近 %s 次的历史密码", 3, 32) {
|
||||
@Override
|
||||
public void validate(String password, int policyValue, UserDO user) {
|
||||
UserPasswordHistoryService userPasswordHistoryService = SpringUtil
|
||||
.getBean(UserPasswordHistoryService.class);
|
||||
ValidationUtils.throwIf(userPasswordHistoryService.isPasswordReused(user
|
||||
.getId(), password, policyValue), this.getDescription().formatted(policyValue));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 登录密码错误锁定账号的次数
|
||||
*/
|
||||
PASSWORD_ERROR_LOCK_COUNT(null, SysConstants.NO, 10) {
|
||||
@Override
|
||||
public void validate(String password, int policyValue, UserDO user) {
|
||||
// 无需此处校验
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 登录密码错误锁定账号的时间(min)
|
||||
*/
|
||||
PASSWORD_ERROR_LOCK_MINUTES(null, 1, 1440) {
|
||||
@Override
|
||||
public void validate(String password, int policyValue, UserDO user) {
|
||||
// 无需此处校验
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 密码到期提前提示(天)
|
||||
*/
|
||||
PASSWORD_EXPIRATION_WARNING_DAYS(null, SysConstants.NO, Integer.MAX_VALUE) {
|
||||
@Override
|
||||
public void validate(String password, int policyValue, UserDO user) {
|
||||
// 无需此处校验
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 密码有效期(天)
|
||||
*/
|
||||
PASSWORD_EXPIRATION_DAYS(null, SysConstants.NO, 999) {
|
||||
@Override
|
||||
public void validate(String password, int policyValue, UserDO user) {
|
||||
// 无需此处校验
|
||||
}
|
||||
},;
|
||||
|
||||
private final String description;
|
||||
private final Integer min;
|
||||
private final Integer max;
|
||||
|
||||
/**
|
||||
* 校验
|
||||
*
|
||||
* @param password 密码
|
||||
* @param policyValue 策略值
|
||||
* @param user 用户信息
|
||||
*/
|
||||
public abstract void validate(String password, int policyValue, UserDO user);
|
||||
}
|
||||
|
@@ -20,7 +20,6 @@ import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.io.file.FileNameUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.ReUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alicp.jetcache.anno.CacheInvalidate;
|
||||
import com.alicp.jetcache.anno.CacheType;
|
||||
@@ -39,7 +38,6 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import top.continew.admin.auth.service.OnlineUserService;
|
||||
import top.continew.admin.common.constant.CacheConstants;
|
||||
import top.continew.admin.common.constant.RegexConstants;
|
||||
import top.continew.admin.common.constant.SysConstants;
|
||||
import top.continew.admin.common.enums.DisEnableStatusEnum;
|
||||
import top.continew.admin.common.util.helper.LoginHelper;
|
||||
@@ -56,7 +54,6 @@ import top.continew.admin.system.model.resp.UserResp;
|
||||
import top.continew.admin.system.service.*;
|
||||
import top.continew.starter.core.constant.StringConstants;
|
||||
import top.continew.starter.core.util.validate.CheckUtils;
|
||||
import top.continew.starter.core.util.validate.ValidationUtils;
|
||||
import top.continew.starter.extension.crud.model.query.PageQuery;
|
||||
import top.continew.starter.extension.crud.model.resp.PageResp;
|
||||
import top.continew.starter.extension.crud.service.CommonUserService;
|
||||
@@ -348,28 +345,16 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserRes
|
||||
*/
|
||||
private int checkPassword(String password, UserDO user) {
|
||||
// 密码最小长度
|
||||
int passwordMinLength = optionService.getValueByCode2Int(PASSWORD_MIN_LENGTH.name());
|
||||
ValidationUtils.throwIf(StrUtil.length(password) < passwordMinLength, PASSWORD_MIN_LENGTH.getDescription()
|
||||
.formatted(passwordMinLength));
|
||||
// 密码是否允许包含正反序账号名
|
||||
int passwordAllowContainUsername = optionService.getValueByCode2Int(PASSWORD_ALLOW_CONTAIN_USERNAME.name());
|
||||
if (passwordAllowContainUsername == SysConstants.NO) {
|
||||
String username = user.getUsername();
|
||||
ValidationUtils.throwIf(StrUtil.containsAnyIgnoreCase(password, username, StrUtil
|
||||
.reverse(username)), PASSWORD_ALLOW_CONTAIN_USERNAME.getDescription());
|
||||
}
|
||||
int passwordMaxLength = PASSWORD_MIN_LENGTH.getMax();
|
||||
ValidationUtils.throwIf(!ReUtil.isMatch(RegexConstants.PASSWORD_TEMPLATE
|
||||
.formatted(passwordMinLength, passwordMaxLength), password), "密码长度为 {}-{} 个字符,支持大小写字母、数字、特殊字符,至少包含字母和数字", passwordMinLength, passwordMaxLength);
|
||||
PASSWORD_MIN_LENGTH.validate(password, optionService.getValueByCode2Int(PASSWORD_MIN_LENGTH.name()), user);
|
||||
// 密码是否必须包含特殊字符
|
||||
int passwordContainSpecialChar = optionService.getValueByCode2Int(PASSWORD_CONTAIN_SPECIAL_CHARACTERS.name());
|
||||
ValidationUtils.throwIf(passwordContainSpecialChar == SysConstants.YES && !ReUtil
|
||||
.isMatch(RegexConstants.SPECIAL_CHARACTER, password), PASSWORD_CONTAIN_SPECIAL_CHARACTERS.getDescription());
|
||||
PASSWORD_CONTAIN_SPECIAL_CHARACTERS.validate(password, optionService
|
||||
.getValueByCode2Int(PASSWORD_CONTAIN_SPECIAL_CHARACTERS.name()), user);
|
||||
// 密码是否允许包含正反序账号名
|
||||
PASSWORD_ALLOW_CONTAIN_USERNAME.validate(password, optionService
|
||||
.getValueByCode2Int(PASSWORD_ALLOW_CONTAIN_USERNAME.name()), user);
|
||||
// 密码重复使用规则
|
||||
int passwordReusePolicy = optionService.getValueByCode2Int(PASSWORD_REUSE_POLICY.name());
|
||||
ValidationUtils.throwIf(userPasswordHistoryService.isPasswordReused(user
|
||||
.getId(), password, passwordReusePolicy), PASSWORD_REUSE_POLICY.getDescription()
|
||||
.formatted(passwordReusePolicy));
|
||||
PASSWORD_REUSE_POLICY.validate(password, passwordReusePolicy, user);
|
||||
return passwordReusePolicy;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user