Explorar el Código

产品拦截列表放到数据库,并且加载到缓存

gaodm hace 5 años
padre
commit
2217a830c4

+ 3 - 0
config-server/src/main/resources/shared/gateway-service-dev.yml

@@ -181,3 +181,6 @@ spring:
 server:
   port: 5050
 
+#网关是否验证产品线接口权限
+lantone:
+  valid: true

+ 3 - 0
config-server/src/main/resources/shared/gateway-service-local.yml

@@ -181,3 +181,6 @@ spring:
 server:
   port: 5050
 
+#网关是否验证产品线接口权限
+lantone:
+  valid: true

+ 3 - 1
config-server/src/main/resources/shared/gateway-service-pre.yml

@@ -191,4 +191,6 @@ spring:
 server:
   port: 5050
 
-
+#网关是否验证产品线接口权限
+lantone:
+  valid: true

+ 3 - 1
config-server/src/main/resources/shared/gateway-service-pro.yml

@@ -181,4 +181,6 @@ spring:
 server:
   port: 5050
 
-
+#网关是否验证产品线接口权限
+lantone:
+  valid: true

+ 3 - 1
config-server/src/main/resources/shared/gateway-service-test.yml

@@ -181,4 +181,6 @@ spring:
 server:
   port: 5050
 
-
+#网关是否验证产品线接口权限
+lantone:
+  valid: true

+ 23 - 0
diagbotman-service/src/main/java/com/diagbot/dto/ServiceFiltersDTO.java

@@ -0,0 +1,23 @@
+package com.diagbot.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @Description:
+ * @author: gaodm
+ * @time: 2020/3/25 13:06
+ */
+@Getter
+@Setter
+public class ServiceFiltersDTO {
+    /**
+     * 产品id
+     */
+    private Long productId;
+
+    /**
+     * api前缀
+     */
+    private String name;
+}

+ 4 - 4
diagbotman-service/src/main/java/com/diagbot/entity/ServiceFilter.java

@@ -50,14 +50,14 @@ public class ServiceFilter implements Serializable {
     private String modifier;
 
     /**
-     * 名称
+     * 产品id
      */
-    private String name;
+    private Long productId;
 
     /**
-     * 产品id
+     * api前缀
      */
-    private Long productId;
+    private String name;
 
     /**
      * 备注

+ 8 - 9
diagbotman-service/src/main/java/com/diagbot/facade/ServiceFilterFacade.java

@@ -1,15 +1,14 @@
 package com.diagbot.facade;
 
-import com.diagbot.dto.RespDTO;
+import com.diagbot.dto.ServiceFiltersDTO;
 import com.diagbot.entity.ServiceFilter;
 import com.diagbot.service.impl.ServiceFilterServiceImpl;
+import com.diagbot.util.BeanUtil;
 import com.diagbot.util.ListUtil;
 import org.springframework.stereotype.Component;
 
-import java.util.HashMap;
+import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
 
 /**
  * @Description: 产品服务过滤
@@ -24,12 +23,12 @@ public class ServiceFilterFacade extends ServiceFilterServiceImpl {
      *
      * @return 服务列表
      */
-    public  Map<String, Long> getServiceFilter() {
-        Map<String, Long> resMap = new HashMap<>();
+    public List<ServiceFiltersDTO> getServiceFilter() {
+        List<ServiceFiltersDTO> res = new ArrayList<>();
         List<ServiceFilter> list = this.getAll();
-        if (ListUtil.isNotEmpty(list)){
-            resMap = list.stream().collect(Collectors.toMap(ServiceFilter::getName, ServiceFilter::getProductId));
+        if (ListUtil.isNotEmpty(list)) {
+            res = BeanUtil.listCopyTo(list, ServiceFiltersDTO.class);
         }
-        return resMap;
+        return res;
     }
 }

+ 3 - 2
diagbotman-service/src/main/java/com/diagbot/web/ServiceFilterController.java

@@ -1,6 +1,7 @@
 package com.diagbot.web;
 
 import com.diagbot.dto.RespDTO;
+import com.diagbot.dto.ServiceFiltersDTO;
 import com.diagbot.facade.ServiceFilterFacade;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -9,7 +10,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import springfox.documentation.annotations.ApiIgnore;
 
-import java.util.Map;
+import java.util.List;
 
 /**
  * @Description: 产品服务过滤
@@ -29,7 +30,7 @@ public class ServiceFilterController {
     @ApiOperation(value = "获取需要appkey和secret的服务信息[by:zhoutg]",
             notes = "接口未用,直接从配置项中读取服务")
     @ApiIgnore
-    public RespDTO<Map<String, Long>> getServiceFilter() {
+    public RespDTO<List<ServiceFiltersDTO>> getServiceFilter() {
         return RespDTO.onSuc(serviceFilterFacade.getServiceFilter());
     }
 

+ 1 - 1
diagbotman-service/src/main/resources/mapper/ServiceFilterMapper.xml

@@ -11,8 +11,8 @@
         <result column="gmt_modified" property="gmtModified"/>
         <result column="creator" property="creator"/>
         <result column="modifier" property="modifier"/>
-        <result column="name" property="name"/>
         <result column="product_id" property="productId"/>
+        <result column="name" property="name"/>
         <result column="remark" property="remark"/>
     </resultMap>
 

+ 2 - 3
docs/031.20200325记录产品操作记录/init_diagbotman.sql

@@ -27,9 +27,8 @@ CREATE TABLE `diag_service_filter` (
   `gmt_modified` datetime NOT NULL DEFAULT '1970-01-01 12:00:00' COMMENT '记录修改时间,如果时间是1970年则表示纪录未修改',
   `creator` varchar(20) NOT NULL DEFAULT '0' COMMENT '创建人,0表示无创建人值',
   `modifier` varchar(20) NOT NULL DEFAULT '0' COMMENT '修改人,如果为0则表示纪录未修改',
-  `name` varchar(50) NOT NULL DEFAULT '' COMMENT '名称',
   `product_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '产品id',
+  `name` varchar(20) NOT NULL DEFAULT '' COMMENT 'api前缀',
   `remark` varchar(255) NOT NULL DEFAULT '' COMMENT '备注',
-  PRIMARY KEY (`id`),
-  UNIQUE KEY `name` (`name`)
+  PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='产品网关过滤(需要使用appkey和secret的url地址)';

+ 20 - 0
gateway-service/src/main/java/com/diagbot/dto/ServiceFilterDTO.java

@@ -0,0 +1,20 @@
+package com.diagbot.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @Description:
+ * @author: gaodm
+ * @time: 2020/3/25 13:06
+ */
+@Getter
+@Setter
+public class ServiceFilterDTO implements Serializable {
+    private Set<String> apiMap;
+    private Map<Long, String> productMap;
+}

+ 23 - 0
gateway-service/src/main/java/com/diagbot/dto/ServiceFiltersDTO.java

@@ -0,0 +1,23 @@
+package com.diagbot.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @Description:
+ * @author: gaodm
+ * @time: 2020/3/25 13:06
+ */
+@Getter
+@Setter
+public class ServiceFiltersDTO {
+    /**
+     * 产品id
+     */
+    private Long productId;
+
+    /**
+     * api前缀
+     */
+    private String name;
+}

+ 31 - 16
gateway-service/src/main/java/com/diagbot/facade/ServiceFilterFacade.java

@@ -1,14 +1,23 @@
 package com.diagbot.facade;
 
 import com.diagbot.dto.RespDTO;
-import com.diagbot.exception.CommonErrorCode;
+import com.diagbot.dto.ServiceFilterDTO;
+import com.diagbot.dto.ServiceFiltersDTO;
+import com.diagbot.util.ListUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Component;
 import org.springframework.web.client.RestTemplate;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
  * @Description: 产品服务过滤
@@ -29,22 +38,28 @@ public class ServiceFilterFacade {
      * @return 服务列表
      */
     @Cacheable(value = SERVICEFILTER, key = "'ServiceFilter'")
-    public RespDTO<Map<String, Long>> getServiceFilterRpc() {
-        try {
-            RespDTO<Map<String, Long>> res
-                    = restTemplate.postForObject("http://diagbotman-service/service_filter/getAll", null, RespDTO.class);
+    public ServiceFilterDTO getServiceFilter() {
+        ServiceFilterDTO serviceFilterDTO = new ServiceFilterDTO();
+        RespDTO<List<LinkedHashMap>> resFilter
+                = restTemplate.postForObject("http://diagbotman-service/service_filter/getAll", null, RespDTO.class);
+        if (resFilter != null && RespDTO.TRUE_CODE.equals(resFilter.code)) {
+            Set<String> apiMap = new HashSet<>();
+            Map<Long, String> productMap = new HashMap<>();
+            if (ListUtil.isNotEmpty(resFilter.data)) {
+                List<ServiceFiltersDTO> serviceFiltersDTOList = new ArrayList<>();
+                for (LinkedHashMap map: resFilter.data){
+                    ServiceFiltersDTO serviceFiltersDTO = new ServiceFiltersDTO();
+                    serviceFiltersDTO.setName(map.get("name").toString());
+                    serviceFiltersDTO.setProductId(Long.valueOf(map.get("productId").toString()));
+                    serviceFiltersDTOList.add(serviceFiltersDTO);
+                }
+                apiMap = serviceFiltersDTOList.stream().distinct().map(ServiceFiltersDTO::getName).collect(Collectors.toSet());
+                productMap = serviceFiltersDTOList.stream().collect(Collectors.toMap(ServiceFiltersDTO::getProductId, ServiceFiltersDTO::getName));
+            }
+            serviceFilterDTO.setApiMap(apiMap);
+            serviceFilterDTO.setProductMap(productMap);
             log.info("读取了拦截产品线缓存!");
-            return res;
-        } catch (Exception ex) {
-            return getServiceFilterFallback();
         }
-    }
-
-    public RespDTO getServiceFilterFallback() {
-        log.error("【hystrix】调用{}异常", "getServiceFilter");
-        RespDTO respDTO = new RespDTO();
-        respDTO.msg = CommonErrorCode.RPC_ERROR.getMsg();
-        respDTO.code = CommonErrorCode.RPC_ERROR.getCode();
-        return respDTO;
+        return serviceFilterDTO;
     }
 }

+ 72 - 49
gateway-service/src/main/java/com/diagbot/filter/GlobalGatewayFilter.java

@@ -4,6 +4,7 @@ package com.diagbot.filter;
 
 import com.diagbot.biz.log.entity.SysLog;
 import com.diagbot.dto.RespDTO;
+import com.diagbot.dto.ServiceFilterDTO;
 import com.diagbot.entity.ServiceFilter;
 import com.diagbot.entity.ServiceToken;
 import com.diagbot.enums.SysTypeEnum;
@@ -12,8 +13,10 @@ import com.diagbot.facade.ServiceFilterFacade;
 import com.diagbot.rabbit.MySender;
 import com.diagbot.util.EnDecodeUtil;
 import com.diagbot.util.GsonUtil;
+import com.diagbot.util.StringUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.cloud.context.config.annotation.RefreshScope;
 import org.springframework.cloud.gateway.filter.GatewayFilterChain;
 import org.springframework.cloud.gateway.filter.GlobalFilter;
@@ -52,8 +55,8 @@ public class GlobalGatewayFilter implements GlobalFilter {
     private static Boolean IS_GENERATE = false;
     private static Map<String, Long> SERVICE_FILTER = new HashMap<>();
 
-    //    @Value("${lantone.product}")
-    //    private String lantonePrduct;
+    @Value("${lantone.valid}")
+    private Boolean lantoneValid;
 
     //    @Autowired
     //    DiagbotmanServiceClient diagbotmanServiceClient;
@@ -66,6 +69,7 @@ public class GlobalGatewayFilter implements GlobalFilter {
 
 
     @Override
+    @SuppressWarnings("unchecked")
     public Mono<Void> filter(ServerWebExchange serverWebExchange, GatewayFilterChain gatewayFilterChain) {
         log.info("check token and url permission....");
         LinkedHashSet requiredAttribute
@@ -85,61 +89,80 @@ public class GlobalGatewayFilter implements GlobalFilter {
             }
         }
 
-        // Map<String, Long> serviceFilters = this.dealServiceFilter();
-        RespDTO<Map<String, Long>> resFilter = serviceFilterFacade.getServiceFilterRpc();
-        if (resFilter == null || !RespDTO.TRUE_CODE.equals(resFilter.code)) {
-            return getVoidMono(serverWebExchange, resFilter);
-        }
-        Map<String, Long> serviceFilters = resFilter.data;
-        if (serviceFilters.get(serviceName) != null) {
-            String appkey = request.getHeaders().getFirst("appKeyId");
-            String secret = request.getHeaders().getFirst("appKeySecret");
-            String securityCode = request.getHeaders().getFirst("securityCode"); //防伪码
+        //网关验证产品线接口权限
+        if (lantoneValid) {
+            ServiceFilterDTO serviceFilterDTO = new ServiceFilterDTO();
             try {
-                String encodeTime = EnDecodeUtil.decode(securityCode);
-                Long time = Long.parseLong(encodeTime);
-                Long curTime = new Date().getTime();
-                // 防伪码主要是为了防止别人窃取url地址后直接长期使用,这边设了失效,目前暂定为24小时
-                // 前端实时获取当前时间跟系统时间作比较,如果时差超出24小时将会抛异常
-                if ((curTime - time) > 1000 * 3600 * 24) {
+                serviceFilterDTO = serviceFilterFacade.getServiceFilter();
+            } catch (Exception e) {
+                RespDTO respDTO = new RespDTO();
+                respDTO.code = CommonErrorCode.RPC_ERROR.getCode();
+                respDTO.msg = CommonErrorCode.RPC_ERROR.getMsg();
+                return getVoidMono(serverWebExchange, respDTO);
+            }
+            if (serviceFilterDTO.getApiMap().contains(serviceName)) {
+                String productIdStr = request.getHeaders().getFirst("productId");
+                if (StringUtil.isNotBlank(productIdStr)) {
+                    RespDTO respDTO = new RespDTO();
+                    respDTO.code = CommonErrorCode.PARAM_IS_NULL.getCode();
+                    respDTO.msg = "请传入产品ID";
+                    return getVoidMono(serverWebExchange, respDTO);
+                }
+                Long productId = Long.valueOf(productIdStr);
+                if (!serviceName.equals(serviceFilterDTO.getProductMap().get(productId))) {
+                    RespDTO respDTO = new RespDTO();
+                    respDTO.code = CommonErrorCode.NOPERMISSION_ERROR.getCode();
+                    respDTO.msg = CommonErrorCode.NOPERMISSION_ERROR.getMsg();
+                    return getVoidMono(serverWebExchange, respDTO);
+                }
+                String appkey = request.getHeaders().getFirst("appKeyId");
+                String secret = request.getHeaders().getFirst("appKeySecret");
+                String securityCode = request.getHeaders().getFirst("securityCode"); //防伪码
+                try {
+                    String encodeTime = EnDecodeUtil.decode(securityCode);
+                    Long time = Long.parseLong(encodeTime);
+                    Long curTime = new Date().getTime();
+                    // 防伪码主要是为了防止别人窃取url地址后直接长期使用,这边设了失效,目前暂定为24小时
+                    // 前端实时获取当前时间跟系统时间作比较,如果时差超出24小时将会抛异常
+                    if ((curTime - time) > 1000 * 3600 * 24) {
+                        RespDTO respDTO = new RespDTO();
+                        respDTO.code = CommonErrorCode.SECURITYCODE_ERROR.getCode();
+                        respDTO.msg = CommonErrorCode.SECURITYCODE_ERROR.getMsg();
+                        return getVoidMono(serverWebExchange, respDTO);
+                    }
+                } catch (Exception e) {
                     RespDTO respDTO = new RespDTO();
                     respDTO.code = CommonErrorCode.SECURITYCODE_ERROR.getCode();
                     respDTO.msg = CommonErrorCode.SECURITYCODE_ERROR.getMsg();
                     return getVoidMono(serverWebExchange, respDTO);
                 }
-            } catch (Exception e) {
-                RespDTO respDTO = new RespDTO();
-                respDTO.code = CommonErrorCode.SECURITYCODE_ERROR.getCode();
-                respDTO.msg = CommonErrorCode.SECURITYCODE_ERROR.getMsg();
-                return getVoidMono(serverWebExchange, respDTO);
-            }
-            Long productId = serviceFilters.get(serviceName);
-            //获取appkey,secret对应的权限信息
-            ServiceToken st = new ServiceToken();
-            st.setAppkey(appkey);
-            st.setSecret(secret);
-            st.setProductId(productId);
-            //权限验证
-            RespDTO<LinkedHashMap> res = hasPermission(st);
-            if (res == null || !RespDTO.TRUE_CODE.equals(res.code)) {
-                return getVoidMono(serverWebExchange, res);
-            }
+                //获取appkey,secret对应的权限信息
+                ServiceToken st = new ServiceToken();
+                st.setAppkey(appkey);
+                st.setSecret(secret);
+                st.setProductId(productId);
+                //权限验证
+                RespDTO<LinkedHashMap> res = hasPermission(st);
+                if (res == null || !RespDTO.TRUE_CODE.equals(res.code)) {
+                    return getVoidMono(serverWebExchange, res);
+                }
 
-            //记录日志
-            SysLog sysLog = new SysLog();
-            sysLog.setGmtCreate(new Date());
-            sysLog.setIp(request.getRemoteAddress().toString());
-            sysLog.setMethod(requestUri);
-            ServiceFilter serviceFilter = new ServiceFilter();
-            serviceFilter.setServiceName(serviceName);
-            serviceFilter.setProductId(productId);
-            sysLog.setOperation(GsonUtil.toJson(serviceFilter));
-            sysLog.setParams(requestUri);
-            sysLog.setSysType(SysTypeEnum.APPKEY.getKey());
-            LinkedHashMap<String, String> map = res.data;
-            sysLog.setUsername(map.get("userId"));
-            mySender.outputLogSend(sysLog);
+                //记录日志
+                SysLog sysLog = new SysLog();
+                sysLog.setGmtCreate(new Date());
+                sysLog.setIp(request.getRemoteAddress().toString());
+                sysLog.setMethod(requestUri);
+                ServiceFilter serviceFilter = new ServiceFilter();
+                serviceFilter.setServiceName(serviceName);
+                serviceFilter.setProductId(productId);
+                sysLog.setOperation(GsonUtil.toJson(serviceFilter));
+                sysLog.setParams(requestUri);
+                sysLog.setSysType(SysTypeEnum.APPKEY.getKey());
+                LinkedHashMap<String, String> map = res.data;
+                sysLog.setUsername(map.get("userId"));
+                mySender.outputLogSend(sysLog);
 
+            }
         }
 
         ServerHttpRequest.Builder builder = serverWebExchange.getRequest().mutate();