Procházet zdrojové kódy

【CHG】密码复杂度限制

zhaomn před 3 roky
rodič
revize
c5e7bd2627

+ 7 - 0
railway-admin/src/main/java/com/railway/web/controller/system/SysProfileController.java

@@ -13,6 +13,7 @@ import com.railway.common.core.redis.RedisCache;
 import com.railway.common.enums.BusinessType;
 import com.railway.common.utils.SecurityUtils;
 import com.railway.common.utils.StringUtils;
+import com.railway.common.utils.WeakPasswordUtils;
 import com.railway.framework.web.service.TokenService;
 import com.railway.system.service.ISysDeptService;
 import com.railway.system.service.ISysFileService;
@@ -162,12 +163,18 @@ public class SysProfileController extends BaseController {
     LoginUser loginUser = getLoginUser();
     String userName = loginUser.getUsername();
     String password = loginUser.getPassword();
+    // 解码
+    oldPassword = SecurityUtils.decode(oldPassword);
+    newPassword = SecurityUtils.decode(newPassword);
     if (!SecurityUtils.matchesPassword(oldPassword, password)) {
       return AjaxResult.error("修改密码失败,旧密码错误");
     }
     if (SecurityUtils.matchesPassword(newPassword, password)) {
       return AjaxResult.error("新密码不能与旧密码相同");
     }
+    if (WeakPasswordUtils.isWeakPassword(newPassword)) {
+      return AjaxResult.error("当前密码为弱密码,请重新设置安全密码!");
+    }
     if (userService.resetUserPwd(userName, SecurityUtils.encryptPassword(newPassword)) > 0) {
       // 更新缓存用户密码
       loginUser.getUser().setPassword(SecurityUtils.encryptPassword(newPassword));

+ 19 - 0
railway-common/src/main/java/com/railway/common/utils/SecurityUtils.java

@@ -5,6 +5,9 @@ import com.railway.common.core.domain.entity.SysRole;
 import com.railway.common.core.domain.entity.SysUser;
 import com.railway.common.core.domain.model.LoginUser;
 import com.railway.common.exception.ServiceException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
 import java.util.List;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContextHolder;
@@ -79,6 +82,22 @@ public class SecurityUtils {
     return passwordEncoder.encode(password);
   }
 
+  /**
+   * 密码解码
+   *
+   * @param password 密码
+   * @return 加密字符串
+   */
+  public static String decode(String password) {
+    String passwordChar = "";
+    try {
+      passwordChar = URLDecoder.decode(password, StandardCharsets.UTF_8.name());
+    } catch (UnsupportedEncodingException e) {
+      e.printStackTrace();
+    }
+    return passwordChar;
+  }
+
   /**
    * 判断密码是否相同
    *

+ 51 - 0
railway-common/src/main/java/com/railway/common/utils/WeakPasswordUtils.java

@@ -0,0 +1,51 @@
+package com.railway.common.utils;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class WeakPasswordUtils {
+
+  public static boolean isWeakPassword(String password) {
+    // 字符长度8 - 16字符
+    // 2个及以上大写字母
+    // 2个及以上小写字母
+    // 1个及以上特殊字符
+    // 3个及以上数字字符
+
+    // 需要满足的基本规则
+    String baseReg = "^(?=.*[A-Z].*[A-Z])(?=.*[!@#$&*])(?=.*[0-9].*[0-9].*[0-9])(?=.*[a-z].*[a-z]).{8,16}$";
+
+    boolean matchBaseReg = password.matches(baseReg);
+    // 不满足要求,认为是弱密码
+    if (!matchBaseReg) {
+      return true;
+    }
+
+    // 需要满足的特征
+    String pattern1 = "([0-9a-zA-Z])\\1{2}";
+    String pattern2 = "(?:0(?=1)|1(?=2)|2(?=3)|3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9)){2}";
+    String pattern3 = "(?:9(?=8)|8(?=7)|7(?=6)|6(?=5)|5(?=4)|4(?=3)|3(?=2)|2(?=1)|1(?=0)){2}";
+
+    boolean weakPassword = isMatchWeakPassword(password, pattern1);
+    if (weakPassword) {
+      return true;
+    }
+    weakPassword = isMatchWeakPassword(password, pattern2);
+    if (weakPassword) {
+      return true;
+    }
+    weakPassword = isMatchWeakPassword(password, pattern3);
+    return weakPassword;
+  }
+
+  public static boolean isMatchWeakPassword(String password, String patternStr) {
+    // 创建 Pattern 对象
+    Pattern pattern = Pattern.compile(patternStr);
+    // 现在创建 matcher 对象
+    Matcher matcher = pattern.matcher(password);
+    // 找到弱密码特征
+    return matcher.find();
+
+  }
+
+}

+ 2 - 1
railway-common/src/main/java/com/railway/common/utils/SignatureUtil.java → railway-common/src/main/java/com/railway/common/utils/sign/SignatureUtil.java

@@ -1,9 +1,10 @@
-package com.railway.common.utils;
+package com.railway.common.utils.sign;
 
 import static com.railway.common.core.domain.dto.ReturnCode.SIGN_CHECK_FAIL;
 
 import com.railway.common.core.domain.AjaxResult;
 import com.railway.common.core.domain.dto.ReturnCode;
+import com.railway.common.utils.DateUtils;
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
 import java.security.InvalidKeyException;

+ 1 - 5
railway-framework/src/main/java/com/railway/framework/interceptor/SignatureInterceptor.java

@@ -3,13 +3,10 @@ package com.railway.framework.interceptor;
 import static com.railway.common.core.domain.dto.ReturnCode.SIGN_CHECK_FAIL;
 
 import com.railway.common.core.domain.AjaxResult;
-import com.railway.common.core.domain.dto.ReturnCode;
-import com.railway.common.utils.DateUtils;
 import com.railway.common.utils.JsonUtil;
-import com.railway.common.utils.SignatureUtil;
+import com.railway.common.utils.sign.SignatureUtil;
 import com.railway.framework.web.service.INeedSignCheck;
 import java.io.UnsupportedEncodingException;
-import java.time.LocalDateTime;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -19,7 +16,6 @@ import javax.annotation.Nonnull;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.lang.NonNull;
 import org.springframework.stereotype.Component;

+ 1 - 4
railway-framework/src/main/java/com/railway/framework/security/advice/SecretRequestAdvice.java

@@ -4,21 +4,18 @@ import com.alibaba.fastjson.JSONObject;
 import com.railway.common.core.domain.AjaxResult;
 import com.railway.common.core.domain.dto.ReturnCode;
 import com.railway.common.exception.base.BaseException;
-import com.railway.common.utils.DateUtils;
 import com.railway.common.utils.JsonUtil;
-import com.railway.common.utils.SignatureUtil;
+import com.railway.common.utils.sign.SignatureUtil;
 import com.railway.framework.web.service.INeedSignCheck;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
 import java.lang.reflect.Type;
-import java.time.LocalDateTime;
 import java.util.Map;
 import java.util.UUID;
 import javax.annotation.Nonnull;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.core.MethodParameter;
 import org.springframework.core.annotation.Order;

+ 16 - 8
railway-framework/src/main/java/com/railway/framework/web/service/SysLoginService.java

@@ -13,6 +13,7 @@ import com.railway.common.exception.user.CaptchaExpireException;
 import com.railway.common.exception.user.UserPasswordNotMatchException;
 import com.railway.common.utils.DateUtils;
 import com.railway.common.utils.MessageUtils;
+import com.railway.common.utils.SecurityUtils;
 import com.railway.common.utils.ServletUtils;
 import com.railway.common.utils.StringUtils;
 import com.railway.common.utils.ip.IpUtils;
@@ -69,8 +70,15 @@ public class SysLoginService {
     boolean captchaOnOff = configService.selectCaptchaOnOff();
     // 验证码开关
     if (captchaOnOff) {
-       validateCaptcha(username, code, uuid);
+      validateCaptcha(username, code, uuid);
     }
+
+    String initPassword = configService.selectConfigByKey("sys.user.initPassword");
+    password = SecurityUtils.decode(password);
+    if (StringUtils.isEmpty(password) || password.equals(initPassword)) {
+      throw new ServiceException("当前登录用密码是初始密码,请修改后重新登录!");
+    }
+
     // 用户验证
     Authentication authentication;
     try {
@@ -132,7 +140,7 @@ public class SysLoginService {
     sysUser.setUserId(userId);
     sysUser.setLoginIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
     sysUser.setLoginDate(DateUtils.getNowDate());
-    if(StringUtils.isNotEmpty(mobileId)) {
+    if (StringUtils.isNotEmpty(mobileId)) {
       sysUser.setMobileId(mobileId);
     }
     userService.updateUserProfile(sysUser);
@@ -146,19 +154,19 @@ public class SysLoginService {
   private void updateJcebSelectedDeptId(LoginUser loginUser) {
     SysUser user = loginUser.getUser();
     List<SysRole> roles = user.getRoles();
-    if(CollectionUtils.isNotEmpty(roles)){
-      for(SysRole role : roles){
+    if (CollectionUtils.isNotEmpty(roles)) {
+      for (SysRole role : roles) {
         PostTypeEnum tmpPostType = PostTypeEnum.ofRoleName(role.getRoleName());
-        if(PostTypeEnum.CENTER == tmpPostType){
+        if (PostTypeEnum.CENTER == tmpPostType) {
           // 从缓存中取本个所选车间
           Long deptId = redisCache.getCacheObject(getCacheKey(loginUser.getUserId()));
-          if(StringUtils.isEmpty(deptId)) {
+          if (StringUtils.isEmpty(deptId)) {
             // 取默认选择的车间
             deptId = redisCache.getCacheObject(Constants.LEADER_VIEW_DEPT_INIT_KEY);
-            if(StringUtils.isEmpty(deptId)){
+            if (StringUtils.isEmpty(deptId)) {
               // 从数据库中查默认选择的车间
               SysDept dept = deptService.selectInitDept();
-              if(null != dept) {
+              if (null != dept) {
                 redisCache.setCacheObject(Constants.LEADER_VIEW_DEPT_INIT_KEY, dept.getDeptId());
                 redisCache.setCacheObject(getCacheKey(loginUser.getUserId()), dept.getDeptId());
               }