|
|
@ -13,6 +13,7 @@ import cn.estsh.impp.framework.boot.exception.ImppBusiException;
|
|
|
|
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
|
|
|
|
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
|
|
|
|
import cn.estsh.impp.framework.boot.util.*;
|
|
|
|
import cn.estsh.impp.framework.boot.util.*;
|
|
|
|
import org.apache.commons.collections.CollectionUtils;
|
|
|
|
import org.apache.commons.collections.CollectionUtils;
|
|
|
|
|
|
|
|
import org.apache.commons.lang3.RandomStringUtils;
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
@ -21,15 +22,16 @@ import org.springframework.context.annotation.Lazy;
|
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
import org.springframework.transaction.annotation.Propagation;
|
|
|
|
import org.springframework.transaction.annotation.Propagation;
|
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
|
|
import org.springframework.util.ObjectUtils;
|
|
|
|
|
|
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
|
import javax.annotation.Resource;
|
|
|
|
import javax.naming.NamingException;
|
|
|
|
import javax.naming.NamingException;
|
|
|
|
import javax.naming.ldap.LdapContext;
|
|
|
|
import javax.naming.ldap.LdapContext;
|
|
|
|
import java.io.UnsupportedEncodingException;
|
|
|
|
import java.io.UnsupportedEncodingException;
|
|
|
|
import java.security.NoSuchAlgorithmException;
|
|
|
|
import java.security.NoSuchAlgorithmException;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.*;
|
|
|
|
import java.util.Objects;
|
|
|
|
|
|
|
|
import java.util.regex.Pattern;
|
|
|
|
import java.util.regex.Pattern;
|
|
|
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @Description :
|
|
|
|
* @Description :
|
|
|
@ -53,6 +55,42 @@ public class SysUserPasswordUtil {
|
|
|
|
protected ImppRedis redisCore;
|
|
|
|
protected ImppRedis redisCore;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 大写字符char数组
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
public static char[] upperChars = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 小写字符char数组
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
public static char[] lowerChars = new char[]{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 数字字符char数字
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
public static char[] numChars = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
|
|
|
|
|
|
|
|
//char[] specialChars = new char[]{' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~'};
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 特殊字符char数组
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
//去除一些特殊字符
|
|
|
|
|
|
|
|
public static char[] specialChars = new char[]{'!', '#', '$', '%', '&', '*', '+', '-', '?', '@', '^', '_', '~'};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 大写字符char数组的名称
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
public static String UPPER_CHAR_ARRAY_NAME = "UPPER";
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 小写字符char数组的名称
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
public static String LOWER_CHAR_ARRAY_NAME = "LOWER";
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 数字字符char数组的名称
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
public static String NUM_CHAR_ARRAY_NAME = "NUM";
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 特殊字符char数组的名称
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
public static String SPECIAL_CHAR_ARRAY_NAME = "SPECIAL";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 密码加密 返回加密信息
|
|
|
|
* 密码加密 返回加密信息
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param password
|
|
|
|
* @param password
|
|
|
@ -275,7 +313,7 @@ public class SysUserPasswordUtil {
|
|
|
|
if (CollectionUtils.isNotEmpty(passwords)) {
|
|
|
|
if (CollectionUtils.isNotEmpty(passwords)) {
|
|
|
|
for (SysUserPassword password : passwords) {
|
|
|
|
for (SysUserPassword password : passwords) {
|
|
|
|
//防止日期转换错误
|
|
|
|
//防止日期转换错误
|
|
|
|
if (StringUtils.isNotBlank(password.getCreateDatetime())){
|
|
|
|
if (StringUtils.isNotBlank(password.getCreateDatetime())) {
|
|
|
|
int day = TimeTool.getSecoundsBetweenTime(4, password.getCreateDatetime(), TimeTool.getNowTime(true));
|
|
|
|
int day = TimeTool.getSecoundsBetweenTime(4, password.getCreateDatetime(), TimeTool.getNowTime(true));
|
|
|
|
if (day < lastDay) {
|
|
|
|
if (day < lastDay) {
|
|
|
|
lastDay = day;
|
|
|
|
lastDay = day;
|
|
|
@ -352,24 +390,24 @@ public class SysUserPasswordUtil {
|
|
|
|
} catch (ImppBusiException e) {
|
|
|
|
} catch (ImppBusiException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
e.printStackTrace();
|
|
|
|
return ResultBean.fail(e);
|
|
|
|
return ResultBean.fail(e);
|
|
|
|
}catch (Exception e){
|
|
|
|
} catch (Exception e) {
|
|
|
|
return ResultBean.fail(e);
|
|
|
|
return ResultBean.fail(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
/* 检查密码有效期 */
|
|
|
|
/* 检查密码有效期 */
|
|
|
|
ResultBean result = checkLoginPasswordTimeOut(user);
|
|
|
|
ResultBean result = checkLoginPasswordTimeOut(user);
|
|
|
|
if(!result.isSuccess()){
|
|
|
|
if (!result.isSuccess()) {
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* 登录 长时间未登录锁定 */
|
|
|
|
/* 登录 长时间未登录锁定 */
|
|
|
|
result = checkLoginTimeOut(user);
|
|
|
|
result = checkLoginTimeOut(user);
|
|
|
|
if(!result.isSuccess()){
|
|
|
|
if (!result.isSuccess()) {
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* 判断是否第一次登录 */
|
|
|
|
/* 判断是否第一次登录 */
|
|
|
|
result = checkFirstLoginChangePwd(user);
|
|
|
|
result = checkFirstLoginChangePwd(user);
|
|
|
|
if(!result.isSuccess()){
|
|
|
|
if (!result.isSuccess()) {
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ResultBean.success();
|
|
|
|
return ResultBean.success();
|
|
|
@ -535,7 +573,7 @@ public class SysUserPasswordUtil {
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
private ResultBean checkLoginTimeOut(SysUser user) {
|
|
|
|
private ResultBean checkLoginTimeOut(SysUser user) {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
if (StringUtils.isBlank(user.getUserLoginLastDateTime())){
|
|
|
|
if (StringUtils.isBlank(user.getUserLoginLastDateTime())) {
|
|
|
|
return ResultBean.success("上次登录时间为空");
|
|
|
|
return ResultBean.success("上次登录时间为空");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
int loginDayMax = RedisCacheTool.getSysConfigIntVal(CommonConstWords.CONFIG_USER_LOGIN_DAY_OUT, CommonConstWords.CONFIG_USER_LOGIN_DAY_OUT_DEFAULT);
|
|
|
|
int loginDayMax = RedisCacheTool.getSysConfigIntVal(CommonConstWords.CONFIG_USER_LOGIN_DAY_OUT, CommonConstWords.CONFIG_USER_LOGIN_DAY_OUT_DEFAULT);
|
|
|
@ -600,4 +638,65 @@ public class SysUserPasswordUtil {
|
|
|
|
return ResultBean.success();
|
|
|
|
return ResultBean.success();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 根据密码安全策略里面的规则生成随机密码,重复性检验和正则表达式检验不进行校验
|
|
|
|
|
|
|
|
* 密码保存规则里面有正则校验,正则校验可能会与其他规则冲突,导致生成的密码无法通过规则校验
|
|
|
|
|
|
|
|
* 目前重置密码不会进行密码规则的校验
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @return string
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
public static String generateRandomPassword() {
|
|
|
|
|
|
|
|
int length = RedisCacheTool.getSysConfigIntVal(CommonConstWords.CONFIG_PWD_LENGTH, CommonConstWords.CONFIG_PWD_LENGTH_DEFAULT);
|
|
|
|
|
|
|
|
//todo: 修改密码长度的接口要做校验,长度不能超过最大值
|
|
|
|
|
|
|
|
if (length < CommonConstWords.CONFIG_PWD_LENGTH_DEFAULT) {
|
|
|
|
|
|
|
|
length = CommonConstWords.CONFIG_PWD_LENGTH_DEFAULT;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//四种类型的字符一定会有,所以先随机占用4个位置
|
|
|
|
|
|
|
|
Random random = new Random();
|
|
|
|
|
|
|
|
String[] typeArray = new String[]{UPPER_CHAR_ARRAY_NAME, LOWER_CHAR_ARRAY_NAME, NUM_CHAR_ARRAY_NAME, SPECIAL_CHAR_ARRAY_NAME};
|
|
|
|
|
|
|
|
char[] randomCharArray = new char[length];
|
|
|
|
|
|
|
|
int top = length;
|
|
|
|
|
|
|
|
int[] indexArray = new int[length];
|
|
|
|
|
|
|
|
for (int i = 0; i < indexArray.length; i++) {
|
|
|
|
|
|
|
|
indexArray[i] = i;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Map<Integer, String> indexMap = new HashMap<>(length);
|
|
|
|
|
|
|
|
//确定四个必须要的字符的位置,剩下的位置的字符随机从四种中选择
|
|
|
|
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
|
|
|
|
|
|
int index = random.nextInt(top);
|
|
|
|
|
|
|
|
indexMap.put(indexArray[index], typeArray[i]);
|
|
|
|
|
|
|
|
indexArray[index] = indexArray[top - 1];
|
|
|
|
|
|
|
|
top--;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < randomCharArray.length; i++) {
|
|
|
|
|
|
|
|
//判断对应字符的位置是否已经被占用
|
|
|
|
|
|
|
|
if (!ObjectUtils.isEmpty(indexMap.get(i))) {
|
|
|
|
|
|
|
|
randomCharArray[i] = getRandomChar(indexMap.get(i), random);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
//todo:这里可以把所有char合并一个数组做减少typeArray的random,直接从所有可选字符合并的大数组里面选一个字符
|
|
|
|
|
|
|
|
randomCharArray[i] = getRandomChar(typeArray[random.nextInt(typeArray.length)], random);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return String.valueOf(randomCharArray);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 根据同的字符类型生成对应类型的随机字符
|
|
|
|
|
|
|
|
* @param key
|
|
|
|
|
|
|
|
* @param random
|
|
|
|
|
|
|
|
* @return
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
public static char getRandomChar(String key, Random random) {
|
|
|
|
|
|
|
|
if (UPPER_CHAR_ARRAY_NAME.equals(key)) {
|
|
|
|
|
|
|
|
return upperChars[random.nextInt(upperChars.length)];
|
|
|
|
|
|
|
|
} else if (LOWER_CHAR_ARRAY_NAME.equals(key)) {
|
|
|
|
|
|
|
|
return lowerChars[random.nextInt(lowerChars.length)];
|
|
|
|
|
|
|
|
} else if (NUM_CHAR_ARRAY_NAME.equals(key)) {
|
|
|
|
|
|
|
|
return numChars[random.nextInt(numChars.length)];
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
return specialChars[random.nextInt(specialChars.length)];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|