Browse Source

鉴权操作从各微服务迁移至网关

tangyishan 1 month ago
parent
commit
4f4d962d3d

+ 19 - 221
sckw-common/sckw-common-core/src/main/java/com/sckw/core/filter/RequestCheckFilter.java

@@ -1,34 +1,20 @@
 package com.sckw.core.filter;
 
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.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.CollectionUtils;
-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 lombok.extern.slf4j.Slf4j;
-import org.redisson.api.RSet;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.Ordered;
 
 import java.io.IOException;
-import java.util.*;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
 
 /**
  * @desc: 登录过滤
@@ -36,222 +22,34 @@ import java.util.*;
  * @date: 2023/6/14
  */
 @Slf4j
-public class RequestCheckFilter implements Filter {
+public class RequestCheckFilter implements Filter, Ordered {
 
-    @Autowired
-    CustomConfig customConfig;
-
-    /**
-     * 直接放行不需要校验Access-Token的请求
-     */
-    private static final List<String> EXCLUDEPATH = new ArrayList<>();
-
-    /**
-     * 直接放行不需要校验Access-Special的请求
-     */
-    private static final List<String> IMPORT_PASS_PATH = new ArrayList<>();
-
-    /**
-     * 需要校验token但不用接口权限校验的请求
-     */
-    private static final List<String> WITHOUTPATH = new ArrayList<>();
-
-    private static final String REGISTER = "/kwsEnt/register";
-
-    /**
-     * @desc: 初始化放行路径
-     * @author: czh
-     */
-    @PostConstruct
-    private void initExcludePath() {
-        String links = customConfig.getLinks();
-        if (StringUtils.isNotBlank(links)) {
-            EXCLUDEPATH.addAll(Arrays.asList(links.split(Global.COMMA)));
-        }
-
-        String specialLinks = customConfig.getSpecialLinks();
-        if (StringUtils.isNotBlank(specialLinks)) {
-            IMPORT_PASS_PATH.addAll(Arrays.asList(links.split(Global.COMMA)));
-        }
-//        String withoutLinks = customConfig.getWithoutLinks();
-//        if (StringUtils.isNotBlank(withoutLinks)) {
-//            WITHOUTPATH.addAll(Arrays.asList(withoutLinks.split(Global.COMMA)));
-//        }
-    }
 
     @Override
     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);
-        Integer systemType = request.getIntHeader(RequestConstant.SYSTEM_TYPE);
-//        String accessSpecial = request.getHeader(RequestConstant.ACCESS_SPECIAL);
-        String requestUri = request.getRequestURI();
-        /*1、非token校验接口放行*/
-        if (EXCLUDEPATH.contains(requestUri)) {
-            filterChain.doFilter(servletRequest, servletResponse);
-            return;
-        }
-        
-        // 添加对Swagger相关路径的放行
-        if (requestUri.startsWith("/swagger-ui") || 
-            requestUri.startsWith("/v3/api-docs") || requestUri.startsWith("/doc.htm")||
-            requestUri.startsWith("/webjars/")) {
-            filterChain.doFilter(servletRequest, servletResponse);
-            return;
-        }
-
-        /*2、校验token**/
-        /*2.1、校验token非空*/
-        HttpResult result = checkBlank(token, clientType, systemType, requestUri);
-        if (result.getCode() != HttpStatus.SUCCESS_CODE) {
-            ResponseUtil.writer(response, result);
-            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 key = Global.getFullUserTokenKey(clientType, userId);
-        String redisUserToken = RedissonUtils.getString(key);
-        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.TOKEN_INVALID_CODE, HttpStatus.ACCOUNT_OTHER_LOGIN_MESSAGE));
-            return;
-        }
-
-        /*3、校验登录用户信息*/
-        key = Global.getFullUserLoginKey(systemType, userId);
-        String userInfoStr = RedissonUtils.getString(key);
-        LoginUserInfo loginUserInfo = StringUtils.isNotBlank(userInfoStr) ? JSON.parseObject(userInfoStr, LoginUserInfo.class) : null;
-        if (Objects.isNull(loginUserInfo)) {
-            ResponseUtil.writer(response, HttpResult.error(HttpStatus.TOKEN_INVALID_CODE, HttpStatus.TOKEN_INVALID_MESSAGE));
-            return;
-        }
-        loginUserInfo.setClientType(clientType);
-
-        //校验用户账号是否冻结
-        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 (SystemTypeEnum.MANAGE.getCode().equals(systemType)) {
-            //redis 获取客户经理绑定企业ID
-            String managerKey = Global.getCustomerManagerUserLoginKey(SystemTypeEnum.MANAGE.getCode(), loginUserInfo.getId());
-            RSet<Object> set = RedissonUtils.getSet(managerKey);
-            if (Objects.nonNull(set)) {
-                List authUserIdList = JSONObject.parseObject(set.toString(), List.class);
-                if (CollectionUtils.isNotEmpty(authUserIdList)) {
-                    loginUserInfo.setAuthEntIdList(authUserIdList);
-                }
-            }
-            LoginUserHolder.set(loginUserInfo);
-            LoginEntHolder.set(loginEntInfo);
-            RedissonUtils.putString(Global.getFullUserTokenKey(clientType, userId), token, ClientTypeEnum.expireTime(clientType));
-            RedissonUtils.putString(Global.getFullUserLoginKey(systemType, loginUserInfo.getId()), JSON.toJSONString(loginUserInfo), Global.APP_TOKEN_EXPIRE);
-            RedissonUtils.putString(Global.getFullUserEntKey(loginEntInfo.getId()), JSON.toJSONString(loginEntInfo), Global.APP_TOKEN_EXPIRE);
-            filterChain.doFilter(servletRequest, servletResponse);
-            LoginUserHolder.remove();
-            return;
-        }
-
-        if ((StringUtils.isBlank(loginEntStr) || loginEntInfo == null) && !Objects.equals(systemType, SystemTypeEnum.MANAGE.getCode())) {
-            ResponseUtil.writer(response, HttpResult.error(HttpStatus.TOKEN_INVALID_CODE, HttpStatus.UN_LOGIN_MESSAGE));
-            return;
-        } else {
-            //校验用户企业是否冻结
-            if (Objects.isNull(loginEntInfo) || loginEntInfo.getStatus() == Global.YES) {
-                ResponseUtil.writer(response, HttpResult.error(HttpStatus.TOKEN_INVALID_CODE, "您所属企业已被冻结,请联系系统管理员!"));
-                return;
-            }
-
-            //校验用户企业审批状态
-            if (!loginEntInfo.getValid() && !REGISTER.equals(requestUri)) {
-                if (loginEntInfo.getApproval() == Global.NO) {
-                    ResponseUtil.writer(response, HttpResult.error(HttpStatus.CODE_60603, HttpStatus.ENTCERTIFICATES_NOT_REGISTER));
-                    return;
-                }
-
-                if (loginEntInfo.getApproval() == Global.NUMERICAL_THREE) {
-                    ResponseUtil.writer(response, HttpResult.error(HttpStatus.CODE_60603, HttpStatus.ENTCERTIFICATES_NOT_PASS));
-                    return;
-                }
-
-                ResponseUtil.writer(response, HttpResult.error(HttpStatus.CODE_60603, HttpStatus.ENTCERTIFICATES_INVAILD));
-                return;
-            }
-        }
-
-        /*5、请求权限校验*/
-        //非管理员有接口权限才放行
-        if (loginUserInfo.getIsMain() == Global.NO
-                && !WITHOUTPATH.contains(requestUri)
-                && !checkMenu(clientType, loginUserInfo.getId(), requestUri)) {
-            ResponseUtil.writer(response, HttpResult.error(HttpStatus.AUTHORITY_NO_CODE, HttpStatus.ACCESS_FIAL));
-            return;
+        String userInfoStrEncode = request.getHeader(Global.USER_INFO_STR_ENCODE);
+        String entInfoStrEncode = request.getHeader(Global.ENT_INFO_STR_ENCODE);
+        LoginUserInfo loginUserInfo = null;
+        LoginEntInfo loginEntInfo = null;
+        if(StringUtils.isNotBlank(userInfoStrEncode)){
+            String userInfoStr = URLDecoder.decode(userInfoStrEncode, StandardCharsets.UTF_8);
+            loginUserInfo = JSON.parseObject(userInfoStr, LoginUserInfo.class);
+        }
+        if(StringUtils.isNotBlank(entInfoStrEncode)){
+            String entInfoStr = URLDecoder.decode(entInfoStrEncode, StandardCharsets.UTF_8);
+            loginEntInfo = JSON.parseObject(entInfoStr, LoginEntInfo.class);
         }
         LoginUserHolder.set(loginUserInfo);
         LoginEntHolder.set(loginEntInfo);
-        RedissonUtils.putString(Global.getFullUserLoginKey(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 true;
-        //return RedissonUtils.contains(Global.REDIS_SYS_MENU_PREFIX + clientType + Global.COLON + userId, url);
-    }
-
-    /**
-     * @param token         token
-     * @param clientType    客户端类型
-     * @param systemType    系统类型
-     * @param accessSpecial 专场标识
-     * @param requestUri    请求地址
-     * @return 校验结果
-     * @desc Hearder内容校验
-     * @author zk
-     * @date 2023/12/14
-     **/
-    private HttpResult checkBlank(String token, String clientType, Integer systemType, String requestUri) {
-        if (StringUtils.isBlank(token)) {
-            return HttpResult.error(HttpStatus.PARAMETERS_MISSING_CODE, HttpStatus.UN_LOGIN_MESSAGE);
-        }
-        if (StringUtils.isBlank(clientType)) {
-            return HttpResult.error(HttpStatus.PARAMETERS_MISSING_CODE, HttpStatus.INVALID_REQUEST);
-        }
-        if (StringUtils.isBlank(systemType)) {
-            return HttpResult.error(HttpStatus.PARAMETERS_MISSING_CODE, HttpStatus.INVALID_REQUEST);
-        }
-        return HttpResult.ok();
+    @Override
+    public int getOrder() {
+        return -1;
     }
-
 }

+ 10 - 1
sckw-common/sckw-common-core/src/main/java/com/sckw/core/model/constant/Global.java

@@ -1,6 +1,5 @@
 package com.sckw.core.model.constant;
 
-import com.sckw.core.common.enums.StringConstant;
 import com.sckw.core.utils.StringUtils;
 
 import java.util.Objects;
@@ -132,6 +131,16 @@ public class Global {
      */
     public static final String USER_LOGIN_CAPTCHA = "userLoginCaptcha:";
 
+    /**
+     * 请求头用户信息键名
+     */
+    public static final String USER_INFO_STR_ENCODE = "userInfoStrEncode";
+
+    /**
+     * 请求头企业信息键名
+     */
+    public static final String ENT_INFO_STR_ENCODE = "entInfoStrEncode";
+
     /**
      * redis用户信息前缀
      */

+ 3 - 1
sckw-common/sckw-common-core/src/main/java/com/sckw/core/utils/EncryUtil.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.sckw.core.model.constant.Global;
 import jakarta.servlet.http.HttpServletRequest;
+import lombok.extern.slf4j.Slf4j;
 import org.bouncycastle.util.encoders.Hex;
 import javax.crypto.Cipher;
 import javax.crypto.KeyGenerator;
@@ -17,6 +18,7 @@ import java.util.*;
  * @create 2019-02-27
  * @description 加密工具类
  */
+@Slf4j
 public class EncryUtil {
     /**可调用EncryUtil.generatorPriKey()方法生成*/
     public static final String PRI_KEY = "127f0400ff8a8b7a20d91dfc60a39725";
@@ -205,7 +207,7 @@ public class EncryUtil {
 
             return JSON.parseObject(decodeStr, HashMap.class);
         } catch (Exception e) {
-            e.printStackTrace();
+            log.error("Access-Token解密失败:{}",e.getMessage());
             return null;
         }
     }

+ 2 - 1
sckw-common/sckw-common-redis/src/main/java/com/sckw/redis/config/RedissonConfig.java

@@ -8,6 +8,7 @@ import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator
 import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
 import com.sckw.redis.utils.RedissonUtils;
 import org.redisson.api.RedissonClient;
+import org.redisson.spring.starter.RedissonAutoConfiguration;
 import org.springframework.boot.autoconfigure.AutoConfiguration;
 import org.springframework.context.annotation.Bean;
 import org.springframework.data.redis.connection.RedisConnectionFactory;
@@ -19,7 +20,7 @@ import org.springframework.data.redis.serializer.StringRedisSerializer;
  * @Author xucaiqin
  * @date 2023-06-01 14:50:29
  */
-@AutoConfiguration
+@AutoConfiguration(before = {RedissonAutoConfiguration.class})
 public class RedissonConfig {
 
     /**

+ 13 - 0
sckw-gateway/pom.xml

@@ -18,6 +18,19 @@
     </properties>
 
     <dependencies>
+        <!-- 核心模块 -->
+        <dependency>
+            <groupId>com.sckw</groupId>
+            <artifactId>sckw-common-core</artifactId>
+            <version>${basic.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework</groupId>
+                    <artifactId>spring-webmvc</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
         <!--web-->
         <dependency>
             <groupId>org.springframework.boot</groupId>

+ 3 - 1
sckw-gateway/src/main/java/com/sckw/gateway/GatewayApplication.java

@@ -1,7 +1,9 @@
 package com.sckw.gateway;
 
+import com.sckw.core.filter.ExceptionFilterConfig;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
 import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
 
 /**
@@ -10,7 +12,7 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
  * @date 2023/5/14 21:12
  **/
 @EnableDiscoveryClient
-@SpringBootApplication
+@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, ExceptionFilterConfig.class})
 public class GatewayApplication {
 
     public static void main(String[] args) {

+ 281 - 0
sckw-gateway/src/main/java/com/sckw/gateway/filter/AuthenticationFilter.java

@@ -0,0 +1,281 @@
+package com.sckw.gateway.filter;
+
+import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+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.CollectionUtils;
+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.model.LoginEntInfo;
+import com.sckw.core.web.model.LoginUserInfo;
+import com.sckw.gateway.pojo.HttpResult;
+import com.sckw.redis.utils.RedissonUtils;
+import jakarta.annotation.PostConstruct;
+import lombok.extern.slf4j.Slf4j;
+import org.redisson.api.RSet;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+import org.springframework.cloud.gateway.filter.GlobalFilter;
+import org.springframework.core.Ordered;
+import org.springframework.core.io.buffer.DataBuffer;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.http.server.reactive.ServerHttpResponse;
+import org.springframework.stereotype.Component;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+
+@Slf4j
+@Component
+public class AuthenticationFilter implements GlobalFilter, Ordered {
+
+    @Autowired
+    CustomConfig customConfig;
+
+    /**
+     * 直接放行不需要校验Access-Token的请求
+     */
+    private static final List<String> EXCLUDEPATH = new ArrayList<>();
+
+    /**
+     * 直接放行不需要校验Access-Special的请求
+     */
+    private static final List<String> IMPORT_PASS_PATH = new ArrayList<>();
+
+    /**
+     * 需要校验token但不用接口权限校验的请求
+     */
+    private static final List<String> WITHOUTPATH = new ArrayList<>();
+
+    private static final String REGISTER = "/kwsEnt/register";
+
+
+    /**
+     * @desc: 初始化放行路径
+     * @author: czh
+     */
+    @PostConstruct
+    private void initExcludePath() {
+        String links = customConfig.getLinks();
+        if (StringUtils.isNotBlank(links)) {
+            EXCLUDEPATH.addAll(Arrays.asList(links.split(Global.COMMA)));
+        }
+
+        String specialLinks = customConfig.getSpecialLinks();
+        if (StringUtils.isNotBlank(specialLinks)) {
+            IMPORT_PASS_PATH.addAll(Arrays.asList(specialLinks.split(Global.COMMA)));
+        }
+//        String withoutLinks = customConfig.getWithoutLinks();
+//        if (StringUtils.isNotBlank(withoutLinks)) {
+//            WITHOUTPATH.addAll(Arrays.asList(withoutLinks.split(Global.COMMA)));
+//        }
+    }
+
+    @Override
+    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
+        ServerHttpRequest request = exchange.getRequest();
+        ServerHttpResponse response = exchange.getResponse();
+        String token = request.getHeaders().getFirst(RequestConstant.TOKEN);
+        String clientType = request.getHeaders().getFirst(RequestConstant.CLIENT_TYPE);
+        String systemTypeStr = request.getHeaders().getFirst(RequestConstant.SYSTEM_TYPE);
+        Integer systemType = systemTypeStr == null ? null : Integer.parseInt(systemTypeStr);
+//        String accessSpecial = request.getHeader(RequestConstant.ACCESS_SPECIAL);
+        String requestUri = request.getPath().value();
+        /*1、非token校验接口放行*/
+        if (EXCLUDEPATH.contains(requestUri)) {
+            return chain.filter(exchange);
+        }
+
+        // 添加对Swagger相关路径的放行
+        if (requestUri.startsWith("/swagger-ui") ||
+                requestUri.startsWith("/v3/api-docs") || requestUri.startsWith("/doc.htm")||
+                requestUri.startsWith("/webjars/")) {
+            return chain.filter(exchange);
+        }
+
+        /*2、校验token**/
+        /*2.1、校验token非空*/
+        HttpResult result = checkBlank(token, clientType, systemType, requestUri);
+        if (result.getCode() != HttpStatus.SUCCESS_CODE) {
+            return writeResponse(response,result.getCode(),result.getMsg());
+        }
+
+        /*2.2、token解析*/
+        Map<String, Object> tokenMap = EncryUtil.descryV2(Global.PRI_KEY, token);
+        if (tokenMap == null) {
+            return writeResponse(response,HttpStatus.TOKEN_INVALID_CODE,HttpStatus.TOKEN_INVALID_MESSAGE);
+        }
+
+        /*2.3、从redis获取用户登录token*/
+        Long userId = StringUtils.isNotBlank(tokenMap.get("userId")) ? NumberUtils.parseLong(tokenMap.get("userId")) : null;
+        String key = Global.getFullUserTokenKey(clientType, userId);
+        String redisUserToken = RedissonUtils.getString(key);
+        if (StringUtils.isBlank(redisUserToken)) {
+            return writeResponse(response,HttpStatus.TOKEN_INVALID_CODE,HttpStatus.TOKEN_INVALID_MESSAGE);
+        }
+
+        /*2.4、请求token和redis中token不一致,说明账号在别处登录了*/
+        if (!token.equals(redisUserToken)) {
+            return writeResponse(response,HttpStatus.TOKEN_INVALID_CODE,HttpStatus.ACCOUNT_OTHER_LOGIN_MESSAGE);
+        }
+
+        /*3、校验登录用户信息*/
+        key = Global.getFullUserLoginKey(systemType, userId);
+        String userInfoStr = RedissonUtils.getString(key);
+        LoginUserInfo loginUserInfo = StringUtils.isNotBlank(userInfoStr) ? JSON.parseObject(userInfoStr, LoginUserInfo.class) : null;
+        if (Objects.isNull(loginUserInfo)) {
+            return writeResponse(response,HttpStatus.TOKEN_INVALID_CODE,HttpStatus.TOKEN_INVALID_MESSAGE);
+        }
+        loginUserInfo.setClientType(clientType);
+
+        //校验用户账号是否冻结
+        if (loginUserInfo.getStatus() == Global.YES) {
+            return writeResponse(response,HttpStatus.TOKEN_INVALID_CODE,"您的账号已被冻结,请联系系统管理员!");
+        }
+
+        /*4、登录中的企业信息*/
+        String loginEntStr = RedissonUtils.getString(Global.getFullUserEntKey(loginUserInfo.getEntId()));
+        LoginEntInfo loginEntInfo = StringUtils.isNotBlank(loginEntStr) ? JSON.parseObject(loginEntStr, LoginEntInfo.class) : null;
+
+        //运营端
+        if (SystemTypeEnum.MANAGE.getCode().equals(systemType)) {
+            //redis 获取客户经理绑定企业ID
+            String managerKey = Global.getCustomerManagerUserLoginKey(SystemTypeEnum.MANAGE.getCode(), loginUserInfo.getId());
+            RSet<Object> set = RedissonUtils.getSet(managerKey);
+            if (Objects.nonNull(set)) {
+                List authUserIdList = JSONObject.parseObject(set.toString(), List.class);
+                if (CollectionUtils.isNotEmpty(authUserIdList)) {
+                    loginUserInfo.setAuthEntIdList(authUserIdList);
+                }
+            }
+            //重置缓存有效期
+            RedissonUtils.putString(Global.getFullUserTokenKey(clientType, userId), token, ClientTypeEnum.expireTime(clientType));
+            RedissonUtils.putString(Global.getFullUserLoginKey(systemType, loginUserInfo.getId()), JSON.toJSONString(loginUserInfo), Global.APP_TOKEN_EXPIRE);
+            RedissonUtils.putString(Global.getFullUserEntKey(loginEntInfo.getId()), JSON.toJSONString(loginEntInfo), Global.APP_TOKEN_EXPIRE);
+            //将用户信息和企业信息放入header方便后续微服务获取
+            ServerWebExchange build = buildNewExchange(exchange,loginUserInfo,loginEntInfo);
+            return chain.filter(build);
+        }
+
+        //非运营端
+        if ((StringUtils.isBlank(loginEntStr) || loginEntInfo == null)) {
+            return writeResponse(response,HttpStatus.TOKEN_INVALID_CODE,HttpStatus.UN_LOGIN_MESSAGE);
+        } else {
+            //校验用户企业是否冻结
+            if (loginEntInfo.getStatus() == Global.YES) {
+                return writeResponse(response,HttpStatus.TOKEN_INVALID_CODE,"您所属企业已被冻结,请联系系统管理员!");
+            }
+
+            //校验用户企业审批状态
+            if (!loginEntInfo.getValid() && !REGISTER.equals(requestUri)) {
+                if (loginEntInfo.getApproval() == Global.NO) {
+                    return writeResponse(response,HttpStatus.CODE_60603,HttpStatus.ENTCERTIFICATES_NOT_REGISTER);
+                }
+
+                if (loginEntInfo.getApproval() == Global.NUMERICAL_THREE) {
+                    return writeResponse(response,HttpStatus.CODE_60603,HttpStatus.ENTCERTIFICATES_NOT_PASS);
+                }
+
+                return writeResponse(response,HttpStatus.CODE_60603,HttpStatus.ENTCERTIFICATES_INVAILD);
+            }
+        }
+
+        /*5、请求权限校验*/
+        //非管理员有接口权限才放行
+        if (loginUserInfo.getIsMain() == Global.NO
+                && !WITHOUTPATH.contains(requestUri)
+                && !checkMenu(clientType, loginUserInfo.getId(), requestUri)) {
+            return writeResponse(response,HttpStatus.AUTHORITY_NO_CODE,HttpStatus.ACCESS_FIAL);
+        }
+        RedissonUtils.putString(Global.getFullUserLoginKey(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));
+        //将用户信息和企业信息放入header方便后续微服务获取
+        ServerWebExchange build = buildNewExchange(exchange,loginUserInfo,loginEntInfo);
+        return chain.filter(build);
+    }
+
+    private ServerWebExchange buildNewExchange(ServerWebExchange exchange, LoginUserInfo loginUserInfo, LoginEntInfo loginEntInfo) {
+        SimplePropertyPreFilter filter = new SimplePropertyPreFilter("id","entTypes", "firmName","approval","status","special");
+        String userInfoStrEncode = URLEncoder.encode(JSON.toJSONString(loginUserInfo), StandardCharsets.UTF_8);
+        String entInfoStrEncode = URLEncoder.encode(JSON.toJSONString(loginEntInfo,filter), StandardCharsets.UTF_8);
+        ServerHttpRequest newRequest = exchange.getRequest().mutate()
+                .headers(h -> {
+                    h.add(Global.USER_INFO_STR_ENCODE, userInfoStrEncode);
+                    h.add(Global.ENT_INFO_STR_ENCODE, entInfoStrEncode);
+                    h.remove(RequestConstant.TOKEN);
+                }).build();
+        return exchange.mutate().request(newRequest).build();
+    }
+
+    /**
+     * 构建返回内容
+     *
+     * @param response ServerHttpResponse
+     * @param code     返回码
+     * @param msg     返回数据
+     * @return Mono
+     */
+    protected Mono<Void> writeResponse(ServerHttpResponse response, Integer code, String msg) {
+        JSONObject message = new JSONObject();
+        message.put("code", code);
+        message.put("msg", msg);
+        byte[] bits = message.toJSONString().getBytes(StandardCharsets.UTF_8);
+        DataBuffer buffer = response.bufferFactory().wrap(bits);
+        response.setStatusCode(org.springframework.http.HttpStatus.OK);
+        // 指定编码,否则在浏览器中会中文乱码
+        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
+        return response.writeWith(Mono.just(buffer));
+    }
+
+
+    /**
+     * @param token         token
+     * @param clientType    客户端类型
+     * @param systemType    系统类型
+     * @param requestUri    请求地址
+     * @return 校验结果
+     * @desc Hearder内容校验
+     * @author zk
+     * @date 2023/12/14
+     **/
+    private HttpResult checkBlank(String token, String clientType, Integer systemType, String requestUri) {
+        if (StringUtils.isBlank(token)) {
+            return HttpResult.error(HttpStatus.PARAMETERS_MISSING_CODE, HttpStatus.UN_LOGIN_MESSAGE);
+        }
+        if (StringUtils.isBlank(clientType)) {
+            return HttpResult.error(HttpStatus.PARAMETERS_MISSING_CODE, HttpStatus.INVALID_REQUEST);
+        }
+        if (StringUtils.isBlank(systemType)) {
+            return HttpResult.error(HttpStatus.PARAMETERS_MISSING_CODE, HttpStatus.INVALID_REQUEST);
+        }
+        return HttpResult.ok();
+    }
+
+    /**
+     * @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 true;
+        //return RedissonUtils.contains(Global.REDIS_SYS_MENU_PREFIX + clientType + Global.COLON + userId, url);
+    }
+
+    @Override
+    public int getOrder() {
+        return 2;
+    }
+}

+ 2 - 2
sckw-gateway/src/main/resources/bootstrap-dev.yml

@@ -19,10 +19,10 @@ spring:
         file-extension: yaml
         shared-configs:
           - data-id: sckw-common.yml
-            group: sckw-common
+            group: sckw-ng-common
             refresh: true
         #可以读多个配置文件 需要在同一个命名空间下面可以是不同的组
         extension-configs:
-          - dataId: sckw-common.yml
+          - data-id: sckw-common.yml
             group: sckw-ng-service-platform
             refresh: true