浏览代码

1、接口访问校验调整;
2、登录调整;

zk 2 年之前
父节点
当前提交
d5fb5e94dd

+ 13 - 11
sckw-auth/src/main/java/com/sckw/auth/service/impl/AuthServiceImpl.java

@@ -19,6 +19,7 @@ import com.sckw.core.web.response.HttpResult;
 import com.sckw.fleet.api.RemoteFleetService;
 import com.sckw.fleet.api.model.vo.RDriverDetailVo;
 import com.sckw.message.api.dubbo.SmsInfoService;
+import com.sckw.redis.constant.RedisConstant;
 import com.sckw.system.api.RemoteSystemService;
 import com.sckw.system.api.model.dto.req.*;
 import com.sckw.system.api.model.dto.res.KwsRoleResDto;
@@ -51,8 +52,8 @@ public class AuthServiceImpl implements IAuthService {
     @DubboReference(version = "1.0.0", group = "design", check = false)
     private RemoteSystemService systemService;
 
-    @DubboReference(version = "1.0.0", group = "design", check = false)
-    private SmsInfoService smsInfoService;
+    /*@DubboReference(version = "1.0.0", group = "design", check = false)
+    private SmsInfoService smsInfoService;*/
 
     @DubboReference(version = "1.0.0", group = "design", check = false)
     private RemoteFleetService fleetService;
@@ -319,7 +320,7 @@ public class AuthServiceImpl implements IAuthService {
             long id = loginResVo.getId();
             List<UserAccessMenuInfoResDto> userAccessMenuInfo = remoteUserService.queryUserAccessMenu(id);
             if (CollectionUtils.isEmpty(userAccessMenuInfo)) {
-                RedissonUtils.delete(Global.REDIS_SYS_MENU_PREFIX + loginResVo.getSystemType() + Global.COLON + id);
+                RedissonUtils.delete(Global.REDIS_SYS_MENU_PREFIX + loginResVo.getClientType() + Global.COLON + id);
                 log.error("未查询到用户{}的菜单权限", id);
                 return;
             }
@@ -331,7 +332,7 @@ public class AuthServiceImpl implements IAuthService {
                     menus.addAll(Arrays.asList(userAccessMenuInfoResDto.getLinks().split(",")));
                 }
             }
-            RedissonUtils.putSet(Global.REDIS_SYS_MENU_PREFIX + id, menus);
+            RedissonUtils.putSet(Global.REDIS_SYS_MENU_PREFIX + loginResVo.getClientType() + Global.COLON + id, menus);
         }
 
         /**
@@ -484,7 +485,10 @@ public class AuthServiceImpl implements IAuthService {
         info.put("clientType", loginBase.getClientType());
         info.put("systemType", loginBase.getSystemType());
         info.put("timestamp", System.currentTimeMillis());
+        String key = Global.getFullUserTokenKey(loginBase.getClientType(), userId);
         String token = EncryUtil.encryV1(Global.PRI_KEY, JSON.toJSONString(info));
+        int expireTime = ClientTypeEnum.expireTime(loginBase.getClientType());
+        RedissonUtils.putString(key, token, expireTime);
         return token;
     }
 
@@ -532,7 +536,7 @@ public class AuthServiceImpl implements IAuthService {
             }
             LoginEntInfo loginEntInfo = new LoginEntInfo();
             BeanUtils.copyProperties(ent, loginEntInfo);
-            String key = Global.REDIS_ENTERPRISE_PREFIX + ent.getId();
+            String key = Global.getFullUserEntKey(loginEntInfo.getId());
             RedissonUtils.putString(key, JSON.toJSONString(loginEntInfo), Global.APP_TOKEN_EXPIRE);
         }
 
@@ -558,10 +562,9 @@ public class AuthServiceImpl implements IAuthService {
             loginUserInfo.setEntId(enterprise != null ? enterprise.getId() : null);
             loginUserInfo.setEntName(enterprise != null ? enterprise.getFirmName() : null);
             loginUserInfo.setClientType(loginBase.getClientType());
-            loginUserInfo.setTimestamp(System.currentTimeMillis());
             int expireTime = ClientTypeEnum.expireTime(loginBase.getClientType());
-            String key = Global.getFullUserLoginKey(loginUserInfo.getSystemType(), loginUserInfo.getId(), loginBase.getClientType());
-            RedissonUtils.putString(key, JSON.toJSONString(loginUserInfo), expireTime);
+            String key = Global.getFullUserLoginKey(loginUserInfo.getSystemType(), loginUserInfo.getId());
+            RedissonUtils.putString(key, JSON.toJSONString(loginUserInfo), Global.APP_TOKEN_EXPIRE);
         }
 
         /**
@@ -586,10 +589,9 @@ public class AuthServiceImpl implements IAuthService {
             loginUserInfo.setIsMain(user.getIsMain());
             loginUserInfo.setEntId(user.getEntId());
             loginUserInfo.setEntName(enterprise != null ? enterprise.getFirmName() : null);
-            loginUserInfo.setTimestamp(System.currentTimeMillis());
             int expireTime = ClientTypeEnum.expireTime(loginBase.getClientType());
-            String key = Global.getFullUserLoginKey(loginUserInfo.getSystemType(), loginUserInfo.getId(), loginBase.getClientType());
-            RedissonUtils.putString(key, JSON.toJSONString(loginUserInfo), expireTime);
+            String key = Global.getFullUserLoginKey(loginUserInfo.getSystemType(), loginUserInfo.getId());
+            RedissonUtils.putString(key, JSON.toJSONString(loginUserInfo), Global.APP_TOKEN_EXPIRE);
 
             //存缓存请求地址
             SaveMenusToCache(user);

+ 116 - 8
sckw-common/sckw-common-core/src/main/java/com/sckw/core/filter/RequestCheckFilter.java

@@ -1,30 +1,44 @@
 package com.sckw.core.filter;
 
+import com.alibaba.fastjson.JSON;
 import com.sckw.core.model.constant.Global;
+import com.sckw.core.model.enums.ClientTypeEnum;
+import com.sckw.core.model.enums.SystemTypeEnum;
+import com.sckw.core.utils.EncryUtil;
+import com.sckw.core.utils.NumberUtils;
 import com.sckw.core.utils.StringUtils;
 import com.sckw.core.web.config.CustomConfig;
+import com.sckw.core.web.constant.HttpStatus;
+import com.sckw.core.web.constant.RequestConstant;
+import com.sckw.core.web.context.LoginEntHolder;
+import com.sckw.core.web.context.LoginUserHolder;
+import com.sckw.core.web.model.LoginEntInfo;
+import com.sckw.core.web.model.LoginUserInfo;
+import com.sckw.core.web.response.HttpResult;
+import com.sckw.core.web.response.ResponseUtil;
+import com.sckw.redis.utils.RedissonUtils;
 import jakarta.annotation.PostConstruct;
 import jakarta.servlet.*;
 import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
 import org.springframework.beans.factory.annotation.Autowired;
-
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
 
 /**
- * @desc 过滤
- * @author zk
- * @date 2023/8/18
+ * @desc: 登录过滤
+ * @author: czh
+ * @date: 2023/6/14
  */
 public class RequestCheckFilter implements Filter {
-
-    private static final List<String> EXCLUDEPATH = new ArrayList<>();
-
     @Autowired
     CustomConfig customConfig;
 
+    private static final List<String> EXCLUDEPATH = new ArrayList<>();
+
     /**
      * @desc: 初始化放行路径
      * @author: czh
@@ -41,15 +55,109 @@ public class RequestCheckFilter implements Filter {
     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                          FilterChain filterChain) throws IOException, ServletException {
         HttpServletRequest request = (HttpServletRequest) servletRequest;
+        HttpServletResponse response = (HttpServletResponse) servletResponse;
+        String token = request.getHeader(RequestConstant.TOKEN);
+        String clientType = request.getHeader(RequestConstant.CLIENT_TYPE);
+        String systemType = request.getHeader(RequestConstant.SYSTEM_TYPE);
         String requestUri = request.getRequestURI();
-        /*1、不用token的接口直接放行*/
+
+        /*1、非token校验接口放行*/
         if (EXCLUDEPATH.contains(requestUri)) {
             filterChain.doFilter(servletRequest, servletResponse);
             return;
         }
 
+        /*2、校验token**/
+        /*2.1、校验token非空*/
+        if (StringUtils.isBlank(token)) {
+            ResponseUtil.writer(response, HttpResult.error(HttpStatus.UN_LOGIN_CODE, HttpStatus.UN_LOGIN_MESSAGE));
+            return;
+        }
+
+        /*2.2、token解析*/
+        Map<String, Object> tokenMap = EncryUtil.descryV2(Global.PRI_KEY, token);
+        if (tokenMap == null) {
+            ResponseUtil.writer(response, HttpResult.error(HttpStatus.TOKEN_INVALID_CODE, HttpStatus.TOKEN_INVALID_MESSAGE));
+            return;
+        }
+
+        /*2.3、从redis获取用户登录token*/
+        Long userId = StringUtils.isNotBlank(tokenMap.get("userId")) ? NumberUtils.parseLong(tokenMap.get("userId")) : null;
+        String redisUserToken = RedissonUtils.getString(Global.getFullUserTokenKey(clientType, userId));
+        if (StringUtils.isBlank(redisUserToken)) {
+            ResponseUtil.writer(response, HttpResult.error(HttpStatus.TOKEN_INVALID_CODE, HttpStatus.TOKEN_INVALID_MESSAGE));
+            return;
+        }
+
+        /*2.4、请求token和redis中token不一致,说明账号在别处登录了*/
+        if (!token.equals(redisUserToken)) {
+            ResponseUtil.writer(response, HttpResult.error(HttpStatus.ACCOUNT_OTHER_LOGIN_CODE, HttpStatus.ACCOUNT_OTHER_LOGIN_MESSAGE));
+            return;
+        }
+
+        /*3、校验登录用户信息*/
+        String key = Global.getFullUserLoginKey(NumberUtils.parseInt(systemType), userId);
+        String userInfoStr = RedissonUtils.getString(key);
+        LoginUserInfo loginUserInfo = StringUtils.isNotBlank(userInfoStr) ? JSON.parseObject(userInfoStr, LoginUserInfo.class) : null;
+        if (StringUtils.isBlank(userInfoStr) || loginUserInfo == null) {
+            ResponseUtil.writer(response, HttpResult.error(HttpStatus.TOKEN_INVALID_CODE, HttpStatus.TOKEN_INVALID_MESSAGE));
+            return;
+        }
+
+        //校验用户账号是否冻结
+        if (loginUserInfo.getStatus() == Global.YES) {
+            ResponseUtil.writer(response, HttpResult.error(HttpStatus.TOKEN_INVALID_CODE, "您的账号已被冻结,请联系系统管理员!"));
+            return;
+        }
+
+        /*4、登录中的企业信息*/
+        String loginEntStr = RedissonUtils.getString(Global.getFullUserEntKey(loginUserInfo.getEntId()));
+        LoginEntInfo loginEntInfo = StringUtils.isNotBlank(loginEntStr) ? JSON.parseObject(loginEntStr, LoginEntInfo.class) : null;
+        if ((StringUtils.isBlank(loginEntStr) || loginEntInfo == null) && NumberUtils.parseInt(systemType) != SystemTypeEnum.MANAGE.getCode()) {
+            ResponseUtil.writer(response, HttpResult.error(HttpStatus.TOKEN_INVALID_CODE, HttpStatus.UN_LOGIN_MESSAGE));
+            return;
+        } else {
+            //校验用户企业是否冻结
+            if (loginEntInfo.getStatus()  == Global.YES) {
+                ResponseUtil.writer(response, HttpResult.error(HttpStatus.TOKEN_INVALID_CODE, "您所属企业已被冻结,请联系系统管理员!"));
+                return;
+            }
+
+            //校验用户企业审批状态
+            if (!loginEntInfo.getValid()) {
+                ResponseUtil.writer(response, HttpResult.error(HttpStatus.QUERY_FAIL_CODE, HttpStatus.ENTCERTIFICATES_INVAILD));
+                return;
+            }
+        }
+
+        /*5、请求权限校验*/
+        //非管理员有接口权限才放行
+        if (loginUserInfo.getIsMain() != Global.YES && !checkMenu(clientType, loginUserInfo.getId(), requestUri)) {
+            ResponseUtil.writer(response, HttpResult.error(HttpStatus.AUTHORITY_NO_CODE, HttpStatus.ACCESS_FIAL));
+            return;
+        }
 
+        LoginUserHolder.set(loginUserInfo);
+        LoginEntHolder.set(loginEntInfo);
+        RedissonUtils.putString(Global.getFullUserTokenKey(clientType, userId), token, ClientTypeEnum.expireTime(clientType));
+        RedissonUtils.putString(Global.getFullUserLoginKey(NumberUtils.parseInt(systemType), loginUserInfo.getId()), JSON.toJSONString(loginUserInfo), Global.APP_TOKEN_EXPIRE);
+        RedissonUtils.putString(Global.getFullUserEntKey(loginEntInfo.getId()), JSON.toJSONString(loginEntInfo), Global.APP_TOKEN_EXPIRE);
+        RedissonUtils.putString(Global.getFullUserTokenKey(clientType, userId), token, ClientTypeEnum.expireTime(clientType));
+        filterChain.doFilter(servletRequest, servletResponse);
+        LoginUserHolder.remove();
+        LoginEntHolder.remove();
+    }
 
 
+
+    /**
+     * @param userId 用户菜单权限key  url 当前请求url
+     * @return boolean
+     * @desc: 校验url权限
+     * @author: czh
+     * @date: 2023/6/28
+     */
+    private boolean checkMenu(String clientType, Long userId, String url) {
+        return RedissonUtils.contains(Global.REDIS_SYS_MENU_PREFIX + clientType + Global.COLON + userId, url);
     }
 }

+ 14 - 2
sckw-common/sckw-common-core/src/main/java/com/sckw/core/model/constant/Global.java

@@ -88,6 +88,7 @@ public class Global {
     /**redis用户信息前缀*/
     public static final String REDIS_USER_LOGIN_PREFIX = "userLoginInfo:";
     public static final String REDIS_USER_PREFIX = "userInfo:";
+    public static final String REDIS_USER_TOKEN_PREFIX = "userToken:";
 
     /**redis企业信息前缀*/
     public static final String REDIS_ENTERPRISE_PREFIX = "enterpriseInfo:";
@@ -254,14 +255,25 @@ public class Global {
     /**已读*/
     public static final Integer READ = 1;
 
+
     /**完整的用户登录信息key*/
     public static String getFullUserLoginKey(Integer systemType, Long userId, String clientType) {
         return REDIS_USER_LOGIN_PREFIX + systemType + COLON + userId + COLON + clientType;
     }
 
+    /**完整的用户登录信息key*/
+    public static String getFullUserLoginKey(Integer systemType, Long userId) {
+        return REDIS_USER_LOGIN_PREFIX + systemType + COLON + userId;
+    }
+
+    /**完整的用户登录tokenkey*/
+    public static String getFullUserTokenKey(String clientType, Long userId) {
+        return REDIS_USER_TOKEN_PREFIX + clientType + COLON + userId;
+    }
+
     /**完整的用户企业信息key*/
-    public static String getFullUserEntKey(Integer systemType, Long userId) {
-        return REDIS_ENTERPRISE_PREFIX + systemType + COLON + userId;
+    public static String getFullUserEntKey(Long entId) {
+        return REDIS_ENTERPRISE_PREFIX + entId;
     }
 
     /**完整的用户菜单信息key*/

+ 46 - 0
sckw-common/sckw-common-core/src/main/java/com/sckw/core/utils/EncryUtil.java

@@ -165,6 +165,52 @@ public class EncryUtil {
     }
 
 
+    /**
+     * 解密
+     * @param appSecret 私钥
+     * @param encryStr 加密了的字符串
+     * @author dengyinghui
+     * #date 2019/02/27
+     * @return
+     */
+    public synchronized static String descryV1(String appSecret, String encryStr) {
+        try {
+            Key key = new SecretKeySpec(toByteArray(appSecret), "AES");
+            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
+            cipher.init(Cipher.DECRYPT_MODE, key);
+            byte[] decodeResult = cipher.doFinal(org.apache.commons.codec.binary.Hex.decodeHex(encryStr));
+            return new String(decodeResult);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+
+    /**
+     * 解密
+     * @param appSecret 私钥
+     * @param encryStr 加密了的字符串
+     * @author dengyinghui
+     * #date 2019/02/27
+     * @return
+     */
+    public synchronized static Map<String, Object> descryV2(String appSecret, String encryStr) {
+        try {
+            Key key = new SecretKeySpec(toByteArray(appSecret), "AES");
+            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
+            cipher.init(Cipher.DECRYPT_MODE, key);
+            byte[] decodeResult = cipher.doFinal(org.apache.commons.codec.binary.Hex.decodeHex(encryStr));
+            String decodeStr = new String(decodeResult);
+
+            return JSON.parseObject(decodeStr, HashMap.class);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+
     /**
      * 解密
      * @param appSecret 私钥

+ 0 - 5
sckw-common/sckw-common-core/src/main/java/com/sckw/core/web/model/LoginUserInfo.java

@@ -55,11 +55,6 @@ public class LoginUserInfo {
      */
     private String entName;
 
-    /**
-     * 时间戳
-     */
-    private Long timestamp;
-
 
     public LoginUserInfo() {
     }

+ 3 - 1
sckw-common/sckw-common-core/src/main/java/com/sckw/core/web/response/ResponseUtil.java

@@ -2,6 +2,8 @@ package com.sckw.core.web.response;
 
 import com.alibaba.fastjson.JSON;
 import jakarta.servlet.http.HttpServletResponse;
+
+import java.io.IOException;
 import java.io.PrintWriter;
 
 /**
@@ -17,7 +19,7 @@ public class ResponseUtil {
      * @param httpResult 相应内容
      * @throws Exception
      */
-    public static void writer(HttpServletResponse response, HttpResult httpResult) throws Exception{
+    public static void writer(HttpServletResponse response, HttpResult httpResult) throws IOException {
         response.setCharacterEncoding("utf-8");
         PrintWriter printWriter = response.getWriter();
         printWriter.write(JSON.toJSONString(httpResult));