فهرست منبع

gateway过滤器

yinhao 4 سال پیش
والد
کامیت
eaaf3346b6

+ 18 - 89
huimv-smart-gateway/src/main/java/com/huimv/gateway/filter/SignVerifyFilter.java

@@ -1,42 +1,28 @@
-/*
 package com.huimv.gateway.filter;
 
-import com.alibaba.fastjson.JSONObject;
+
 import com.huimv.common.utils.Constant;
 import com.huimv.gateway.utils.JdkSignatureUtil;
-import io.netty.buffer.ByteBufAllocator;
+import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Value;
 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.core.io.buffer.DataBufferUtils;
-import org.springframework.core.io.buffer.NettyDataBufferFactory;
 import org.springframework.http.HttpStatus;
-import org.springframework.http.server.reactive.ServerHttpRequest;
-import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
 import org.springframework.http.server.reactive.ServerHttpResponse;
 import org.springframework.stereotype.Component;
 import org.springframework.web.server.ServerWebExchange;
-import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
 
-import java.net.URI;
 import java.net.URLDecoder;
-import java.nio.CharBuffer;
-import java.nio.charset.StandardCharsets;
-
 import java.util.Comparator;
 import java.util.Map;
-import java.util.concurrent.atomic.AtomicReference;
 
-*/
 /**
  * @Author yinhao
  * @Date 2021/5/6 9:26
  * @Description
- *//*
+ */
 
 @Slf4j
 @Component
@@ -46,85 +32,29 @@ public class  SignVerifyFilter implements GlobalFilter, Ordered {
 //    private
 //    String PUBLIC_KEY;
 
+    @SneakyThrows
     @Override
     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
 
-        ServerHttpRequest serverHttpRequest = exchange.getRequest();
         ServerHttpResponse response = exchange.getResponse();
-        String method = serverHttpRequest.getMethodValue();
-        if ("POST".equals(method)) {
-            //从请求里获取Post请求体
-            String bodyStr = resolveBodyFromRequest(serverHttpRequest);
-            //TODO 得到Post请求的请求参数后,做你想做的事
-            JSONObject jsonObject = JSONObject.parseObject(bodyStr);
-            String sign = jsonObject.getString("sign");
-            try {
-                String decode = URLDecoder.decode(sign, "UTF-8");
-                StringBuilder sb = new StringBuilder();
-                jsonObject.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getKey)).forEach(entry ->
-                        sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&"));
-                String paramStr = sb.toString().substring(0, sb.length() - 1);
-                boolean result = JdkSignatureUtil.verifySignature(Constant.RSA_SIGN_PUBLIC_KEY,decode,paramStr);
-                if (!result) {
-                    response.setStatusCode(HttpStatus.FORBIDDEN);
-                    return response.setComplete();
-                }
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-
 
-            //下面的将请求体再次封装写回到request里,传到下一级,否则,由于请求体已被消费,后续的服务将取不到值
-            URI uri = serverHttpRequest.getURI();
-            ServerHttpRequest request = serverHttpRequest.mutate().uri(uri).build();
-            DataBuffer bodyDataBuffer = stringBuffer(bodyStr);
-            Flux<DataBuffer> bodyFlux = Flux.just(bodyDataBuffer);
-
-            request = new ServerHttpRequestDecorator(request) {
-                @Override
-                public Flux<DataBuffer> getBody() {
-                    return bodyFlux;
-                }
-            };
-            //封装request,传给下一级
-            return chain.filter(exchange.mutate().request(request).build());
-        } else if ("GET".equals(method)) {
-            Map requestQueryParams = serverHttpRequest.getQueryParams();
-            //TODO 得到Get请求的请求参数后,做你想做的事
-
-            return chain.filter(exchange);
+        Map<String,Object> requestBody = exchange.getAttribute("cachedRequestBodyObject");
+        if (requestBody != null) {
+            String sign = (String) requestBody.remove("sign");
+            String decodeSign = URLDecoder.decode(sign, "UTF-8");
+            StringBuilder sb = new StringBuilder();
+            requestBody.entrySet().forEach(entry ->
+                    sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&")
+            );
+            String paramStr = sb.toString().substring(0, sb.length() - 1);
+            boolean result = JdkSignatureUtil.verifySignature(Constant.RSA_SIGN_PUBLIC_KEY, decodeSign, paramStr);
+            if (!result) {
+                response.setStatusCode(HttpStatus.FORBIDDEN);
+                return response.setComplete();
+            }
         }
         return chain.filter(exchange);
-    }
-
-    */
-/**
-     * 从Flux<DataBuffer>中获取字符串的方法
-     *
-     * @return 请求体
-     *//*
-
-    private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest) {
-        //获取请求体
-        Flux<DataBuffer> body = serverHttpRequest.getBody();
-
-        AtomicReference<String> bodyRef = new AtomicReference<>();
-        body.subscribe(buffer -> {
-            CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());
-            DataBufferUtils.release(buffer);
-            bodyRef.set(charBuffer.toString());
-        });
-        //获取request body
-        return bodyRef.get();
-    }
-
-    private DataBuffer stringBuffer(String value) {
-        byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
 
-        NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
-        DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length);
-        buffer.write(bytes);
-        return buffer;
     }
 
     @Override
@@ -132,4 +62,3 @@ public class  SignVerifyFilter implements GlobalFilter, Ordered {
         return 1;
     }
 }
-*/

+ 2 - 2
huimv-smart-gateway/src/main/java/com/huimv/gateway/filter/TokenSignFilter.java

@@ -64,7 +64,7 @@ public class TokenSignFilter implements GlobalFilter, Ordered {
             return response.setComplete();
         }
 
-        String random = requestBody.get("random");
+        /*String random = requestBody.get("random");
         String timestamp = requestBody.get("timestamp");
         String sign = requestBody.get("sign");
 
@@ -76,7 +76,7 @@ public class TokenSignFilter implements GlobalFilter, Ordered {
         if (!sign.equals(twoSign)){
             response.setStatusCode(HttpStatus.UNAUTHORIZED);
             return response.setComplete();
-        }
+        }*/
 
 
         //登录接口不参与过滤

+ 36 - 0
huimv-smart-gateway/src/main/java/com/huimv/gateway/sign/Signature.java

@@ -0,0 +1,36 @@
+package com.huimv.gateway.sign;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * @author huimv
+ *
+ */
+@Target({TYPE, METHOD})
+@Retention(RUNTIME)
+@Documented
+public @interface Signature {
+
+    /**
+     * 按照order值排序
+     */
+    String ORDER_SORT = "ORDER_SORT";
+
+    /**
+     * 字典序排序
+     */
+    String ALPHA_SORT = "ALPHA_SORT";
+
+    /**
+     * 允许重复请求
+     */
+    boolean resubmit() default true;
+
+    String sort() default Signature.ALPHA_SORT;
+}

+ 25 - 0
huimv-smart-gateway/src/main/java/com/huimv/gateway/sign/SignatureField.java

@@ -0,0 +1,25 @@
+package com.huimv.gateway.sign;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * @author huimv
+ */
+@Target({FIELD})
+@Retention(RUNTIME)
+@Documented
+public @interface SignatureField {
+    //签名顺序
+    int order() default 0;
+
+    //字段name自定义值
+    String customName() default "";
+
+    //字段value自定义值
+    String customValue() default "";
+}

+ 6 - 0
huimv-smart-gateway/src/main/resources/application.yml

@@ -18,6 +18,12 @@ spring:
 #              - OPTION
 #            maxAge: 1800
       routes:
+        - id: managment_route
+          uri: http://192.168.1.57:9200
+          predicates:
+            - Path=/api/management/**
+          filters:
+            - RewritePath=/api/management/(?<segment>/?.*), /$\{segment}
         # renren-fast后台管理系统的路由(低优先级的放在下面)
         - id: admin_route
           uri: http://192.168.1.57:9500

+ 2 - 6
huimv-smart-management/src/main/java/com/huimv/management/Abc.java

@@ -1,10 +1,6 @@
 package com.huimv.management;
 
-import cn.hutool.core.date.DateTime;
-import cn.hutool.core.date.DateUnit;
-import cn.hutool.core.date.DateUtil;
-import com.huimv.common.utils.R;
-import com.huimv.management.rsa.Constants;
+import com.huimv.common.utils.Constant;
 import com.huimv.management.rsa.JdkSignatureUtil;
 
 import java.security.InvalidKeyException;
@@ -38,7 +34,7 @@ public class Abc {
 
         String paramStr = sb.toString();
 
-        String sign = JdkSignatureUtil.executeSignature(Constants.RSA_SIGN_PRIVATE_KEY, paramStr);
+        String sign = JdkSignatureUtil.executeSignature(Constant.RSA_SIGN_PRIVATE_KEY, paramStr);
 
         System.out.println(paramStr);
 

+ 11 - 6
huimv-smart-management/src/main/java/com/huimv/management/rsa/ClientController.java

@@ -1,5 +1,6 @@
 package com.huimv.management.rsa;
 
+import com.huimv.common.utils.Constant;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.client.RestTemplate;
 
@@ -33,11 +34,15 @@ public class ClientController {
     public static String sender() throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, SignatureException, UnsupportedEncodingException {
         // 请求所需的参数
         Map<String, Object> requestParam = new HashMap<>(16);
-        requestParam.put("userName", "小明");
-        requestParam.put("phone", "15866552236");
-        requestParam.put("address", "北京");
-        requestParam.put("status", 1);
-        
+//        requestParam.put("userName", "小明");
+//        requestParam.put("phone", "15866552236");
+//        requestParam.put("address", "北京");
+//        requestParam.put("status", 1);
+        requestParam.put("token", "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhdXRoMCIsImV4cCI6MTYyMDM2OTY4NH0.5XdV22FSaCaJFuLkWGN-SajCn4VXD0S1Hi6wcr1Vz78");
+        requestParam.put("random", 10050);
+        requestParam.put("timestamp", System.currentTimeMillis());
+//        requestParam.put("status", 1);
+
         // 将需要签名的参数内容按参数名的字典顺序进行排序,并拼接为字符串
         StringBuilder sb = new StringBuilder();
         requestParam.entrySet().stream().sorted(
@@ -47,7 +52,7 @@ public class ClientController {
         System.out.println("paramStr:" + paramStr);
         
         // 使用私钥生成签名字符串
-        String sign = JdkSignatureUtil.executeSignature(PRIVATE_KEY, paramStr);
+        String sign = JdkSignatureUtil.executeSignature(Constant.RSA_SIGN_PRIVATE_KEY, paramStr);
         
         // 对签名字符串进行url编码
         String urlEncodeSign = URLEncoder.encode(sign, "UTF-8");

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 12
huimv-smart-management/src/main/java/com/huimv/management/rsa/Constants.java


+ 0 - 35
huimv-smart-management/src/main/java/com/huimv/management/rsa/RSAUtil.java

@@ -1,35 +0,0 @@
-//package com.huimv.management.rsa;
-//
-//import org.apache.tomcat.util.codec.binary.Base64;
-//
-//import java.security.KeyFactory;
-//import java.security.PrivateKey;
-//import java.security.Signature;
-//import java.security.spec.PKCS8EncodedKeySpec;
-//
-///**
-// * @Author yinhao
-// * @Date 2021/4/29 17:53
-// * @Description
-// */
-//public class RSAUtil {
-//
-//    public static void main(String[] args) {
-//        String channelId = "1018";
-//        int random = (int) ((Math.random() * 9 + 1) * 100000);
-//        long timestamp = System.currentTimeMillis();
-//        String data = channelId + ";" + random + ";" + timestamp;
-//        String sign = getPinAnSign(data.getBytes("UTF-8"), Constants.RSA_SIGN_PRIVATE_KEY);
-//    }
-//
-//    private static String getPinAnSign(byte[] data, String privateKey) throws Exception {
-//        byte[] keyBytes = Base64.decodeBase64(privateKey);
-//        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
-//        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
-//        PrivateKey privateKey1 = keyFactory.generatePrivate(pkcs8KeySpec);
-//        Signature signature = Signature.getInstance("MD5withRSA");
-//        signature.initSign(privateKey1);
-//        signature.update(data);
-//    }
-//
-//}

+ 2 - 1
huimv-smart-management/src/main/java/com/huimv/management/rsa/ServerController.java

@@ -10,6 +10,7 @@ import java.security.spec.InvalidKeySpecException;
 import java.util.Comparator;
 import java.util.Map;
 
+import com.huimv.common.utils.Constant;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RestController;
@@ -38,7 +39,7 @@ public class ServerController {
         String paramStr = sb.toString().substring(0, sb.length() - 1);
 
         // 使用公钥进行验签
-        boolean result = JdkSignatureUtil.verifySignature(PUBLIC_KEY, decodeSign, paramStr);
+        boolean result = JdkSignatureUtil.verifySignature(Constant.RSA_SIGN_PUBLIC_KEY, decodeSign, paramStr);
         if (result) {
             return "签名验证成功";
         }

+ 4 - 3
huimv-smart-management/src/main/java/com/huimv/management/rsa/SignRSAUtil.java

@@ -21,9 +21,10 @@ public class SignRSAUtil {
         long timestamp = System.currentTimeMillis();
         String data = channelId + ";" + random + ";" + timestamp;
 
-        String sign = getPinAnSign(data.getBytes(StandardCharsets.UTF_8), Constants.RSA_SIGN_PRIVATE_KEY);
-        String decrypt = decrypt(sign, Constants.RSA_SIGN_PUBLIC_KEY);
-        System.out.println(decrypt);
+//        String sign = getPinAnSign(data.getBytes(StandardCharsets.UTF_8), Constants.RSA_SIGN_PRIVATE_KEY);
+//        System.out.println(sign);
+//        String decrypt = decrypt(sign, Constants.RSA_SIGN_PUBLIC_KEY);
+//        System.out.println(decrypt);
 
 
     }