diff --git a/fizz-bootstrap/pom.xml b/fizz-bootstrap/pom.xml
index 8fa9732..2d241e1 100644
--- a/fizz-bootstrap/pom.xml
+++ b/fizz-bootstrap/pom.xml
@@ -34,7 +34,7 @@
1.15
2.11.1
2.8.8
- 2.0.45.Final
+ 2.0.46.Final
2.2.9.RELEASE
1.7.1
diff --git a/fizz-bootstrap/src/main/resources/application.yml b/fizz-bootstrap/src/main/resources/application.yml
index f82b807..22dc9cf 100644
--- a/fizz-bootstrap/src/main/resources/application.yml
+++ b/fizz-bootstrap/src/main/resources/application.yml
@@ -122,19 +122,20 @@ fizz:
enable: false
port: 8601
request:
- timeliness: 300 # default 300 sec
- timeout: 0 # default no timeout
- retry-count: 0 # default no retry
- retry-interval: 0 # default no retry interval
- service-registration:
-# type: eureka # service registration type, can be eureka or nacos
-# application: ax # register the name of this application to server
-# port: 8601 # the port to be registered
-# service-url: http://6.6.6.6:6600/eureka/ # server address
- type: nacos
- application: ax
- port: 8601
- service-url: 6.6.6.6:8848
+ timeliness: 300 # default 300 sec
+ timeout: 0 # default no timeout
+ retry-count: 0 # default no retry
+ retry-interval: 0 # default no retry interval
+ secret-key: # if key configured, client will encrypt request body and decrypt response body
+# service-registration:
+# type: eureka # service registration type, can be eureka or nacos
+# application: ax # register the name of this application to server
+# port: 8601 # the port to be registered
+# service-url: http://6.6.6.6:6600/eureka/ # server address
+# type: nacos
+# application: ax
+# port: 8601
+# service-url: 6.6.6.6:8848
fizz-trace-id:
header: X-Trace-Id
diff --git a/fizz-common/pom.xml b/fizz-common/pom.xml
index 647de04..87d1c0b 100644
--- a/fizz-common/pom.xml
+++ b/fizz-common/pom.xml
@@ -105,6 +105,11 @@
commons-codec
commons-codec
+
+
+ cn.hutool
+ hutool-crypto
+
diff --git a/fizz-common/src/main/java/we/spring/http/server/reactive/ext/FizzServerHttpRequestDecorator.java b/fizz-common/src/main/java/we/spring/http/server/reactive/ext/FizzServerHttpRequestDecorator.java
index 42ea1d7..a38b5d4 100644
--- a/fizz-common/src/main/java/we/spring/http/server/reactive/ext/FizzServerHttpRequestDecorator.java
+++ b/fizz-common/src/main/java/we/spring/http/server/reactive/ext/FizzServerHttpRequestDecorator.java
@@ -36,6 +36,7 @@ import we.util.NettyDataBufferUtils;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
+import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -60,7 +61,9 @@ public class FizzServerHttpRequestDecorator extends ServerHttpRequestDecorator {
@Nullable
private MultiValueMap cookies;
- private Flux body = Flux.empty();
+ private Flux body = Flux.empty();
+
+ private byte[] bodyBytes;
public FizzServerHttpRequestDecorator(ServerHttpRequest delegate) {
super(delegate);
@@ -128,16 +131,20 @@ public class FizzServerHttpRequestDecorator extends ServerHttpRequestDecorator {
}
public void setEmptyBody() {
- this.body = Flux.empty();
+ body = Flux.empty();
+ bodyBytes = null;
}
public void setBody(DataBuffer body) {
if (body instanceof PooledDataBuffer) {
- byte[] bytes = new byte[body.readableByteCount()];
- body.read(bytes);
+ byte[] bytes = NettyDataBufferUtils.copyBytes(body);
setBody(bytes);
} else {
this.body = Flux.just(body);
+ ByteBuffer byteBuffer = body.asByteBuffer();
+ if (byteBuffer.hasArray()) {
+ bodyBytes = byteBuffer.array();
+ }
}
}
@@ -147,7 +154,8 @@ public class FizzServerHttpRequestDecorator extends ServerHttpRequestDecorator {
}
public void setBody(byte[] body) {
- NettyDataBuffer from = NettyDataBufferUtils.from(body);
+ bodyBytes = body;
+ NettyDataBuffer from = NettyDataBufferUtils.from(bodyBytes);
this.body = Flux.just(from);
}
@@ -156,13 +164,7 @@ public class FizzServerHttpRequestDecorator extends ServerHttpRequestDecorator {
return body;
}
-// public DataBuffer getRawBody() {
-// final DataBuffer[] raw = {null};
-// body.subscribe(
-// dataBuffer -> {
-// raw[0] = dataBuffer;
-// }
-// );
-// return raw[0];
-// }
+ public byte[] getBodyBytes() {
+ return bodyBytes;
+ }
}
diff --git a/fizz-common/src/main/java/we/spring/http/server/reactive/ext/FizzServerHttpResponseDecorator.java b/fizz-common/src/main/java/we/spring/http/server/reactive/ext/FizzServerHttpResponseDecorator.java
index 7f85718..f0f1cdd 100644
--- a/fizz-common/src/main/java/we/spring/http/server/reactive/ext/FizzServerHttpResponseDecorator.java
+++ b/fizz-common/src/main/java/we/spring/http/server/reactive/ext/FizzServerHttpResponseDecorator.java
@@ -46,7 +46,7 @@ public abstract class FizzServerHttpResponseDecorator extends ServerHttpResponse
if (body != NettyDataBufferUtils.EMPTY_DATA_BUFFER) {
if (body instanceof PooledDataBuffer) {
try {
- b = NettyDataBufferUtils.from(body.asByteBuffer());
+ b = NettyDataBufferUtils.copy2heap(body);
} finally {
NettyDataBufferUtils.release(body);
}
diff --git a/fizz-common/src/main/java/we/util/NettyDataBufferUtils.java b/fizz-common/src/main/java/we/util/NettyDataBufferUtils.java
index 1b809ae..9670c00 100644
--- a/fizz-common/src/main/java/we/util/NettyDataBufferUtils.java
+++ b/fizz-common/src/main/java/we/util/NettyDataBufferUtils.java
@@ -54,15 +54,25 @@ public abstract class NettyDataBufferUtils extends org.springframework.core.io.b
return (NettyDataBuffer) dataBufferFactory.wrap(bytes);
}
- public static NettyDataBuffer from(ByteBuffer byteBuffer) {
+ /*public static NettyDataBuffer from(ByteBuffer byteBuffer) {
return dataBufferFactory.wrap(byteBuffer);
}
public static NettyDataBuffer from(ByteBuf byteBuf) {
return dataBufferFactory.wrap(byteBuf);
+ }*/
+
+ public static byte[] copyBytes(DataBuffer dataBuffer) {
+ byte[] bytes = new byte[dataBuffer.readableByteCount()];
+ dataBuffer.read(bytes);
+ return bytes;
}
- public static boolean release(@Nullable String traceId, @Nullable DataBuffer dataBuffer) {
+ public static DataBuffer copy2heap(DataBuffer dataBuffer) {
+ return from(copyBytes(dataBuffer));
+ }
+
+ /*public static boolean release(@Nullable String traceId, @Nullable DataBuffer dataBuffer) {
if (dataBuffer instanceof PooledDataBuffer) {
PooledDataBuffer pooledDataBuffer = (PooledDataBuffer) dataBuffer;
if (pooledDataBuffer.isAllocated()) {
@@ -81,5 +91,5 @@ public abstract class NettyDataBufferUtils extends org.springframework.core.io.b
}
}
return false;
- }
+ }*/
}
diff --git a/fizz-common/src/main/java/we/util/SymmetricCryptoUtils.java b/fizz-common/src/main/java/we/util/SymmetricCryptoUtils.java
new file mode 100644
index 0000000..9a7fd30
--- /dev/null
+++ b/fizz-common/src/main/java/we/util/SymmetricCryptoUtils.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2020 the original author or authors.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package we.util;
+
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.crypto.KeyUtil;
+import cn.hutool.crypto.Padding;
+import cn.hutool.crypto.SecureUtil;
+import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.PBEParameterSpec;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * @author hongqiaowei
+ */
+
+public abstract class SymmetricCryptoUtils {
+
+ private SymmetricCryptoUtils() {
+ }
+
+ public static Cipher createCipher(SymmetricAlgorithm algorithm, String key, int mode) {
+ byte[] keyBytes = SecureUtil.decode(key);
+ String algorithmName = algorithm.getValue();
+ SecretKey secretKey = KeyUtil.generateKey(algorithmName, keyBytes);
+
+ Cipher cipher = SecureUtil.createCipher(algorithmName);
+
+ byte[] iv = cipher.getIV();
+ AlgorithmParameterSpec parameterSpec = null;
+ if (StrUtil.startWithIgnoreCase(algorithmName, "AES")) {
+ if (iv != null) {
+ parameterSpec = new IvParameterSpec(iv);
+ }
+ } else if (StrUtil.startWithIgnoreCase(algorithmName, "PBE")) {
+ if (null == iv) {
+ iv = RandomUtil.randomBytes(8);
+ }
+ parameterSpec = new PBEParameterSpec(iv, 100);
+ }
+
+ try {
+ if (null == parameterSpec) {
+ cipher.init(mode, secretKey);
+ } else {
+ cipher.init(mode, secretKey, parameterSpec);
+ }
+ } catch (InvalidAlgorithmParameterException | InvalidKeyException e) {
+ throw new RuntimeException(e);
+ }
+
+ return cipher;
+ }
+
+ public static boolean isZeroPadding(SymmetricAlgorithm algorithm) {
+ String algorithmName = algorithm.getValue();
+ return algorithmName.contains(Padding.ZeroPadding.name());
+ }
+
+ public static byte[] paddingWith0(byte[] data, int blockSize) {
+ int length = data.length;
+ int remainLength = length % blockSize;
+ if (remainLength > 0) {
+ return ArrayUtil.resize(data, length + blockSize - remainLength);
+ } else {
+ return data;
+ }
+ }
+
+ public static byte[] removePadding(byte[] data, int blockSize) {
+ if (blockSize > 0) {
+ int length = data.length;
+ int remainLength = length % blockSize;
+ if (remainLength == 0) {
+ int i = length - 1;
+ while (i >= 0 && 0 == data[i]) {
+ i--;
+ }
+ return ArrayUtil.resize(data, i + 1);
+ }
+ }
+ return data;
+ }
+}
diff --git a/fizz-common/src/main/java/we/util/SymmetricDecryptor.java b/fizz-common/src/main/java/we/util/SymmetricDecryptor.java
new file mode 100644
index 0000000..8fb06ec
--- /dev/null
+++ b/fizz-common/src/main/java/we/util/SymmetricDecryptor.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2020 the original author or authors.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package we.util;
+
+import cn.hutool.core.util.CharsetUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.crypto.SecureUtil;
+import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+
+/**
+ * @author hongqiaowei
+ */
+
+public class SymmetricDecryptor {
+
+ public final SymmetricAlgorithm algorithm;
+
+ public final String secretKey;
+
+ private final Cipher cipher;
+
+ private final boolean isZeroPadding;
+
+ public SymmetricDecryptor(SymmetricAlgorithm algorithm, String key) {
+ this.algorithm = algorithm;
+ secretKey = key;
+ cipher = SymmetricCryptoUtils.createCipher(algorithm, key, Cipher.DECRYPT_MODE);
+ isZeroPadding = SymmetricCryptoUtils.isZeroPadding(algorithm);
+ }
+
+ /**
+ * @param data can be hex or base64 string
+ */
+ public String decrypt(String data) {
+ byte[] decode = SecureUtil.decode(data);
+ return StrUtil.str(decrypt(decode), CharsetUtil.CHARSET_UTF_8);
+ }
+
+ public byte[] decrypt(byte[] data) {
+ int blockSize = cipher.getBlockSize();
+ byte[] decryptData;
+ try {
+ decryptData = cipher.doFinal(data);
+ } catch (IllegalBlockSizeException | BadPaddingException e) {
+ throw new RuntimeException(e);
+ }
+ if (isZeroPadding) {
+ return SymmetricCryptoUtils.removePadding(decryptData, blockSize);
+ } else {
+ return decryptData;
+ }
+ }
+}
diff --git a/fizz-common/src/main/java/we/util/SymmetricEncryptor.java b/fizz-common/src/main/java/we/util/SymmetricEncryptor.java
new file mode 100644
index 0000000..c81c13d
--- /dev/null
+++ b/fizz-common/src/main/java/we/util/SymmetricEncryptor.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2020 the original author or authors.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package we.util;
+
+import cn.hutool.core.codec.Base64;
+import cn.hutool.core.util.CharsetUtil;
+import cn.hutool.core.util.HexUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+
+/**
+ * @author hongqiaowei
+ */
+
+public class SymmetricEncryptor {
+
+ public final SymmetricAlgorithm algorithm;
+
+ public final String secretKey;
+
+ private final Cipher cipher;
+
+ private final boolean isZeroPadding;
+
+ public SymmetricEncryptor(SymmetricAlgorithm algorithm, String key) {
+ this.algorithm = algorithm;
+ secretKey = key;
+ cipher = SymmetricCryptoUtils.createCipher(algorithm, key, Cipher.ENCRYPT_MODE);
+ isZeroPadding = SymmetricCryptoUtils.isZeroPadding(algorithm);
+ }
+
+ public byte[] encrypt(byte[] data) {
+ if (isZeroPadding) {
+ data = SymmetricCryptoUtils.paddingWith0(data, cipher.getBlockSize());
+ }
+ try {
+ return cipher.doFinal(data);
+ } catch (IllegalBlockSizeException | BadPaddingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public byte[] encrypt(String data) {
+ return encrypt(StrUtil.bytes(data, CharsetUtil.CHARSET_UTF_8));
+ }
+
+ public String base64encrypt(String data) {
+ return Base64.encode(encrypt(data));
+ }
+
+ public String hexEncrypt(String data) {
+ return HexUtil.encodeHexStr(encrypt(data));
+ }
+}
diff --git a/fizz-common/src/main/java/we/util/Utils.java b/fizz-common/src/main/java/we/util/Utils.java
index 776187c..341ba5d 100644
--- a/fizz-common/src/main/java/we/util/Utils.java
+++ b/fizz-common/src/main/java/we/util/Utils.java
@@ -132,4 +132,15 @@ public abstract class Utils {
return new Throwable(msg, null, false, false) {
};
}
+
+ public static String getMessage(Throwable t) {
+ String message = t.getMessage();
+ if (message == null) {
+ StringBuilder b = new StringBuilder();
+ b.append(t.toString()).append(Consts.S.LF);
+ b.append("at ").append(t.getStackTrace()[0].toString());
+ message = b.toString();
+ }
+ return message;
+ }
}
diff --git a/fizz-common/src/test/java/we/util/SymmetricCryptoTests.java b/fizz-common/src/test/java/we/util/SymmetricCryptoTests.java
new file mode 100644
index 0000000..14ad470
--- /dev/null
+++ b/fizz-common/src/test/java/we/util/SymmetricCryptoTests.java
@@ -0,0 +1,24 @@
+package we.util;
+
+import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class SymmetricCryptoTests {
+
+ @Test
+ public void encryptTest() {
+ String secretKey = "1gG1dVcEaQz8JyifTHeEnQ==";
+ SymmetricEncryptor symmetricEncryptor = new SymmetricEncryptor(SymmetricAlgorithm.AES, secretKey);
+ String encrypt = symmetricEncryptor.base64encrypt("abc");
+
+ SymmetricDecryptor symmetricDecryptor = new SymmetricDecryptor(SymmetricAlgorithm.AES, secretKey);
+ String decrypt = symmetricDecryptor.decrypt(encrypt);
+
+ Assertions.assertEquals("abc", decrypt);
+
+ byte[] encryptBytes = symmetricEncryptor.encrypt("123".getBytes());
+ byte[] decryptBytes = symmetricDecryptor.decrypt(encryptBytes);
+ Assertions.assertEquals("123", new String(decryptBytes));
+ }
+}
diff --git a/fizz-core/src/main/java/we/config/SystemConfig.java b/fizz-core/src/main/java/we/config/SystemConfig.java
index cb38349..9812ea8 100644
--- a/fizz-core/src/main/java/we/config/SystemConfig.java
+++ b/fizz-core/src/main/java/we/config/SystemConfig.java
@@ -114,6 +114,9 @@ public class SystemConfig {
@Value("${fizz.dedicated-line.client.request.retry-interval:0}")
private int fizzDedicatedLineClientRequestRetryInterval = 0; // mills
+ @Value("${fizz.dedicated-line.client.request.secret-key:}")
+ private String fizzDedicatedLineClientRequestSecretkey;
+
public int fizzDedicatedLineClientRequestTimeout() {
return fizzDedicatedLineClientRequestTimeout;
}
@@ -130,6 +133,10 @@ public class SystemConfig {
return fizzDedicatedLineClientRequestTimeliness;
}
+ public String fizzDedicatedLineClientRequestSecretkey() {
+ return fizzDedicatedLineClientRequestSecretkey;
+ }
+
public String fizzTraceIdHeader() {
diff --git a/fizz-core/src/main/java/we/dedicated_line/DedicatedLineHttpHandler.java b/fizz-core/src/main/java/we/dedicated_line/DedicatedLineHttpHandler.java
index ca7a692..dfbd6b0 100644
--- a/fizz-core/src/main/java/we/dedicated_line/DedicatedLineHttpHandler.java
+++ b/fizz-core/src/main/java/we/dedicated_line/DedicatedLineHttpHandler.java
@@ -17,11 +17,15 @@
package we.dedicated_line;
+import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext;
import org.springframework.core.NestedExceptionUtils;
+import org.springframework.core.io.buffer.DataBuffer;
+import org.springframework.core.io.buffer.PooledDataBuffer;
import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.http.server.reactive.HttpHandler;
@@ -35,12 +39,11 @@ import org.springframework.web.server.adapter.DefaultServerWebExchange;
import org.springframework.web.server.adapter.ForwardedHeaderTransformer;
import org.springframework.web.server.i18n.LocaleContextResolver;
import org.springframework.web.server.session.WebSessionManager;
+import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import we.config.SystemConfig;
import we.proxy.FizzWebClient;
-import we.util.Consts;
-import we.util.ThreadContext;
-import we.util.WebUtils;
+import we.util.*;
import java.net.URI;
import java.util.Arrays;
@@ -61,6 +64,10 @@ class DedicatedLineHttpHandler implements HttpHandler {
private static final Set disconnected_client_exceptions = new HashSet<>(Arrays.asList("AbortedException", "ClientAbortException", "EOFException", "EofException"));
+ private static final String symmetricEncryptor = "symmEncpT";
+
+ private static final String symmetricDecryptor = "symmDecpT";
+
private WebSessionManager sessionManager;
private ServerCodecConfigurer serverCodecConfigurer;
private LocaleContextResolver localeContextResolver;
@@ -69,7 +76,7 @@ class DedicatedLineHttpHandler implements HttpHandler {
private SystemConfig systemConfig;
private FizzWebClient fizzWebClient;
- private DedicatedLineInfoService dedicatedLineInfoService;
+ private DedicatedLineInfoService dedicatedLineInfoService;
public DedicatedLineHttpHandler(ReactiveWebServerApplicationContext applicationContext, WebSessionManager sessionManager, ServerCodecConfigurer codecConfigurer,
LocaleContextResolver localeContextResolver, ForwardedHeaderTransformer forwardedHeaderTransformer) {
@@ -108,36 +115,25 @@ class DedicatedLineHttpHandler implements HttpHandler {
DedicatedLineInfo dedicatedLineInfo = dedicatedLineInfoService.get(service);
if (dedicatedLineInfo == null) {
log.warn("{}{} service no dedicated line info", logPrefix, service);
- return WebUtils.response(response, HttpStatus.FORBIDDEN, null, service + " service no dedicated line info").then(response.setComplete());
+ return WebUtils.response(response, HttpStatus.FORBIDDEN, null, logPrefix + ' ' + service + " service no dedicated line info");
}
- StringBuilder b = ThreadContext.getStringBuilder();
- b.append(dedicatedLineInfo.url).append(path);
- String qry = requestURI.getQuery();
- if (StringUtils.hasText(qry)) {
- if (org.apache.commons.lang3.StringUtils.indexOfAny(qry, Consts.S.LEFT_BRACE, Consts.S.FORWARD_SLASH, Consts.S.HASH) > 0) {
- qry = requestURI.getRawQuery();
- }
- b.append(Consts.S.QUESTION).append(qry);
- }
- String targetUrl = b.toString();
- String pairCodeId = dedicatedLineInfo.pairCodeId;
- String secretKey = dedicatedLineInfo.secretKey;
- String timestamp = String.valueOf(System.currentTimeMillis());
- String sign = DedicatedLineUtils.sign(pairCodeId, timestamp, secretKey);
-
- HttpHeaders writableHttpHeaders = HttpHeaders.writableHttpHeaders(request.getHeaders());
- writableHttpHeaders.set(SystemConfig.FIZZ_DL_ID, pairCodeId);
- writableHttpHeaders.set(SystemConfig.FIZZ_DL_TS, timestamp);
- writableHttpHeaders.set(SystemConfig.FIZZ_DL_SIGN, sign);
+ String targetUrl = constructTargetUrl(requestURI, path, dedicatedLineInfo.url);
+ HttpHeaders writableHttpHeaders = signAndSetHeaders(request.getHeaders(), dedicatedLineInfo.pairCodeId, dedicatedLineInfo.secretKey);
int requestTimeout = systemConfig.fizzDedicatedLineClientRequestTimeout();
int retryCount = systemConfig.fizzDedicatedLineClientRequestRetryCount();
int retryInterval = systemConfig.fizzDedicatedLineClientRequestRetryInterval();
try {
- // TODO: 如果有请求体,则对请求体加密
- Mono remoteResponseMono = fizzWebClient.send( request.getId(), request.getMethod(), targetUrl, writableHttpHeaders, request.getBody(),
+ Flux dataBufferFlux = request.getBody();
+ Flux bodyFlux = dataBufferFlux;
+ if (StringUtils.hasLength(systemConfig.fizzDedicatedLineClientRequestSecretkey()) && request.getMethod() != HttpMethod.GET) {
+ bodyFlux = encrypt(dataBufferFlux);
+ writableHttpHeaders.remove(HttpHeaders.CONTENT_LENGTH);
+ }
+
+ Mono remoteResponseMono = fizzWebClient.send( request.getId(), request.getMethod(), targetUrl, writableHttpHeaders, bodyFlux,
requestTimeout, retryCount, retryInterval );
Mono respMono = remoteResponseMono.flatMap(
@@ -151,24 +147,124 @@ class DedicatedLineHttpHandler implements HttpHandler {
WebUtils.response2stringBuilder(logPrefix, remoteResp, sb);
log.debug(sb.toString());
}
- // TODO: 如果有响应体,则对响应体解密;响应可能是页面、表单、文件上传的结果、图片等
- return response.writeWith ( remoteResp.body(BodyExtractors.toDataBuffers()) )
- .doOnError ( throwable -> cleanup(remoteResp) )
- .doOnCancel( () -> cleanup(remoteResp) );
+ Flux remoteRespBody = remoteResp.body(BodyExtractors.toDataBuffers());
+ if (StringUtils.hasLength(systemConfig.fizzDedicatedLineClientRequestSecretkey())) {
+ respHeaders.remove(HttpHeaders.CONTENT_LENGTH);
+ return response.writeWith (decrypt(remoteRespBody));
+ } else {
+ return response.writeWith (remoteRespBody)
+ .doOnError ( throwable -> cleanup(remoteResp) )
+ .doOnCancel( () -> cleanup(remoteResp) );
+ }
}
);
return respMono.doOnSuccess ( v -> logResponse(exchange) )
- .onErrorResume( t -> handleUnresolvedError(exchange, t) )
- .then ( Mono.defer(response::setComplete) );
+ .onErrorResume( t -> handleUnresolvedError(exchange, t) );
+ //.then ( Mono.defer(response::setComplete) );
} catch (Throwable t) {
log.error(logPrefix + "500 Server Error for " + formatRequest(request), t);
- response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
- return response.setComplete();
+ return WebUtils.response(response, HttpStatus.INTERNAL_SERVER_ERROR, null, logPrefix + ' ' + Utils.getMessage(t));
}
}
+ private Flux encrypt(Flux bodyFlux) {
+ return NettyDataBufferUtils.join(bodyFlux).defaultIfEmpty(NettyDataBufferUtils.EMPTY_DATA_BUFFER)
+ .flatMap(
+ body -> {
+ if (body == NettyDataBufferUtils.EMPTY_DATA_BUFFER) {
+ return Mono.empty();
+ } else {
+ byte[] bytes = null;
+ if (body instanceof PooledDataBuffer) {
+ try {
+ bytes = NettyDataBufferUtils.copyBytes(body);
+ } finally {
+ NettyDataBufferUtils.release(body);
+ }
+ } else {
+ bytes = body.asByteBuffer().array();
+ }
+ String cryptoKey = systemConfig.fizzDedicatedLineClientRequestSecretkey();
+ SymmetricEncryptor encryptor = (SymmetricEncryptor) ThreadContext.get(symmetricEncryptor);
+ if (encryptor == null) {
+ encryptor = new SymmetricEncryptor(SymmetricAlgorithm.AES, cryptoKey);
+ ThreadContext.set(symmetricEncryptor, encryptor);
+ } else {
+ if (!encryptor.secretKey.equals(cryptoKey)) {
+ encryptor = new SymmetricEncryptor(SymmetricAlgorithm.AES, cryptoKey);
+ ThreadContext.set(symmetricEncryptor, encryptor);
+ }
+ }
+ DataBuffer from = NettyDataBufferUtils.from(encryptor.encrypt(bytes));
+ return Mono.just(from);
+ }
+ }
+ )
+ .flux();
+ }
+
+ private Flux decrypt(Flux bodyFlux) {
+ return NettyDataBufferUtils.join(bodyFlux).defaultIfEmpty(NettyDataBufferUtils.EMPTY_DATA_BUFFER)
+ .flatMap(
+ body -> {
+ if (body == NettyDataBufferUtils.EMPTY_DATA_BUFFER) {
+ return Mono.empty();
+ } else {
+ byte[] bytes = null;
+ if (body instanceof PooledDataBuffer) {
+ try {
+ bytes = NettyDataBufferUtils.copyBytes(body);
+ } finally {
+ NettyDataBufferUtils.release(body);
+ }
+ } else {
+ bytes = body.asByteBuffer().array();
+ }
+ String cryptoKey = systemConfig.fizzDedicatedLineClientRequestSecretkey();
+ SymmetricDecryptor decryptor = (SymmetricDecryptor) ThreadContext.get(symmetricDecryptor);
+ if (decryptor == null) {
+ decryptor = new SymmetricDecryptor(SymmetricAlgorithm.AES, cryptoKey);
+ ThreadContext.set(symmetricDecryptor, decryptor);
+ } else {
+ if (!decryptor.secretKey.equals(cryptoKey)) {
+ decryptor = new SymmetricDecryptor(SymmetricAlgorithm.AES, cryptoKey);
+ ThreadContext.set(symmetricDecryptor, decryptor);
+ }
+ }
+ DataBuffer from = NettyDataBufferUtils.from(decryptor.decrypt(bytes));
+ return Mono.just(from);
+ }
+ }
+ )
+ .flux();
+ }
+
+ private String constructTargetUrl(URI requestURI, String path, String serverAddress) {
+ StringBuilder b = ThreadContext.getStringBuilder();
+ b.append(serverAddress).append(path);
+ String qry = requestURI.getQuery();
+ if (StringUtils.hasText(qry)) {
+ if (org.apache.commons.lang3.StringUtils.indexOfAny(qry, Consts.S.LEFT_BRACE, Consts.S.FORWARD_SLASH, Consts.S.HASH) > 0) {
+ qry = requestURI.getRawQuery();
+ }
+ b.append(Consts.S.QUESTION).append(qry);
+ }
+ return b.toString();
+ }
+
+ private HttpHeaders signAndSetHeaders(HttpHeaders headers, String pairCodeId, String secretKey) {
+ String timestamp = String.valueOf(System.currentTimeMillis());
+ String sign = DedicatedLineUtils.sign(pairCodeId, timestamp, secretKey);
+
+ HttpHeaders writableHttpHeaders = HttpHeaders.writableHttpHeaders(headers);
+ writableHttpHeaders.set(SystemConfig.FIZZ_DL_ID, pairCodeId);
+ writableHttpHeaders.set(SystemConfig.FIZZ_DL_TS, timestamp);
+ writableHttpHeaders.set(SystemConfig.FIZZ_DL_SIGN, sign);
+ return writableHttpHeaders;
+ }
+
private void cleanup(ClientResponse clientResponse) {
if (clientResponse != null) {
clientResponse.bodyToMono(Void.class).subscribe();
@@ -200,7 +296,7 @@ class DedicatedLineHttpHandler implements HttpHandler {
if (response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR)) {
log.error(logPrefix + "500 Server Error for " + formatRequest(request), t);
- return Mono.empty();
+ return WebUtils.response(response, null, null, logPrefix + ' ' + Utils.getMessage(t));
} else if (isDisconnectedClientError(t)) {
if (lostClientLog.isTraceEnabled()) {
@@ -208,7 +304,7 @@ class DedicatedLineHttpHandler implements HttpHandler {
} else if (lostClientLog.isDebugEnabled()) {
lostClientLog.debug(logPrefix + "Client went away: " + t + " (stacktrace at TRACE level for '" + disconnected_client_log_category + "')");
}
- return Mono.empty();
+ return WebUtils.response(response, null, null, logPrefix + ' ' + Utils.getMessage(t));
} else {
// After the response is committed, propagate errors to the server...
diff --git a/fizz-core/src/main/java/we/filter/CallbackFilter.java b/fizz-core/src/main/java/we/filter/CallbackFilter.java
index e5291f0..57fa36b 100644
--- a/fizz-core/src/main/java/we/filter/CallbackFilter.java
+++ b/fizz-core/src/main/java/we/filter/CallbackFilter.java
@@ -103,10 +103,8 @@ public class CallbackFilter extends FizzWebFilter {
DataBuffer body = null;
if (b != NettyDataBufferUtils.EMPTY_DATA_BUFFER) {
if (b instanceof PooledDataBuffer) {
- byte[] bytes = new byte[b.readableByteCount()];
try {
- b.read(bytes);
- body = NettyDataBufferUtils.from(bytes);
+ body = NettyDataBufferUtils.copy2heap(b);
} finally {
NettyDataBufferUtils.release(b);
}
diff --git a/fizz-plugin/src/main/java/we/plugin/dedicatedline/auth/DedicatedLineApiAuthPluginFilter.java b/fizz-plugin/src/main/java/we/plugin/dedicatedline/auth/DedicatedLineApiAuthPluginFilter.java
index 7fe7bc9..68fcc69 100644
--- a/fizz-plugin/src/main/java/we/plugin/dedicatedline/auth/DedicatedLineApiAuthPluginFilter.java
+++ b/fizz-plugin/src/main/java/we/plugin/dedicatedline/auth/DedicatedLineApiAuthPluginFilter.java
@@ -27,6 +27,7 @@ import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import we.dedicated_line.DedicatedLineService;
+import we.flume.clients.log4j2appender.LogService;
import we.plugin.FizzPluginFilter;
import we.plugin.FizzPluginFilterChain;
import we.util.ReactorUtils;
@@ -76,7 +77,7 @@ public class DedicatedLineApiAuthPluginFilter implements FizzPluginFilter {
return WebUtils.response(exchange, HttpStatus.UNAUTHORIZED, null, respJson);
}
} catch (Exception e) {
- log.error("{} {} exception", traceId, DEDICATED_LINE_API_AUTH_PLUGIN_FILTER, e);
+ log.error("{} {} exception", traceId, DEDICATED_LINE_API_AUTH_PLUGIN_FILTER, LogService.BIZ_ID, traceId, e);
String respJson = WebUtils.jsonRespBody(HttpStatus.INTERNAL_SERVER_ERROR.value(),
HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase(), traceId);
return WebUtils.response(exchange, HttpStatus.INTERNAL_SERVER_ERROR, null, respJson);
diff --git a/fizz-plugin/src/main/java/we/plugin/dedicatedline/codec/DedicatedLineCodecPluginFilter.java b/fizz-plugin/src/main/java/we/plugin/dedicatedline/codec/DedicatedLineCodecPluginFilter.java
index 5d30ab5..9cc5918 100644
--- a/fizz-plugin/src/main/java/we/plugin/dedicatedline/codec/DedicatedLineCodecPluginFilter.java
+++ b/fizz-plugin/src/main/java/we/plugin/dedicatedline/codec/DedicatedLineCodecPluginFilter.java
@@ -17,11 +17,9 @@
package we.plugin.dedicatedline.codec;
-import java.nio.charset.StandardCharsets;
-import java.util.Map;
-
-import javax.annotation.Resource;
-
+import cn.hutool.crypto.SecureUtil;
+import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
+import cn.hutool.crypto.symmetric.SymmetricCrypto;
import org.apache.commons.lang3.StringUtils;
import org.reactivestreams.Publisher;
import org.slf4j.Logger;
@@ -35,97 +33,123 @@ import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
-
-import cn.hutool.crypto.SecureUtil;
-import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
-import cn.hutool.crypto.symmetric.SymmetricCrypto;
import reactor.core.publisher.Mono;
import we.config.SystemConfig;
import we.dedicated_line.DedicatedLineService;
import we.flume.clients.log4j2appender.LogService;
import we.plugin.FizzPluginFilterChain;
-import we.plugin.auth.App;
-import we.plugin.auth.AppService;
import we.plugin.requestbody.RequestBodyPlugin;
import we.spring.http.server.reactive.ext.FizzServerHttpRequestDecorator;
import we.spring.http.server.reactive.ext.FizzServerHttpResponseDecorator;
+import we.util.Consts;
import we.util.NettyDataBufferUtils;
import we.util.WebUtils;
+import javax.annotation.Resource;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+
/**
- *
* @author Francis Dong
- *
*/
@ConditionalOnBean(DedicatedLineService.class)
@Component(DedicatedLineCodecPluginFilter.DEDICATED_LINE_CODEC_PLUGIN_FILTER)
public class DedicatedLineCodecPluginFilter extends RequestBodyPlugin {
- private static final Logger log = LoggerFactory.getLogger(DedicatedLineCodecPluginFilter.class);
+ private static final Logger log = LoggerFactory.getLogger(DedicatedLineCodecPluginFilter.class);
- public static final String DEDICATED_LINE_CODEC_PLUGIN_FILTER = "dedicatedLineCodecPlugin";
+ public static final String DEDICATED_LINE_CODEC_PLUGIN_FILTER = "dedicatedLineCodecPlugin";
- @Resource
- private SystemConfig systemConfig;
+ @Resource
+ private SystemConfig systemConfig;
- @Resource
- private DedicatedLineService dedicatedLineService;
+ @Resource
+ private DedicatedLineService dedicatedLineService;
- @SuppressWarnings({ "unchecked", "rawtypes" })
- @Override
- public Mono doFilter(ServerWebExchange exchange, Map config) {
- String traceId = WebUtils.getTraceId(exchange);
- try {
- LogService.setBizId(traceId);
- String dedicatedLineId = WebUtils.getDedicatedLineId(exchange);
- String secretKey = dedicatedLineService.getPairCodeSecretKey(dedicatedLineId);
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ @Override
+ public Mono doFilter(ServerWebExchange exchange, Map config) {
+ String traceId = WebUtils.getTraceId(exchange);
+ try {
+ LogService.setBizId(traceId);
+ String dedicatedLineId = WebUtils.getDedicatedLineId(exchange);
+ // String secretKey = dedicatedLineService.getPairCodeSecretKey(dedicatedLineId);
- FizzServerHttpRequestDecorator request = (FizzServerHttpRequestDecorator) exchange.getRequest();
- return request.getBody().defaultIfEmpty(NettyDataBufferUtils.EMPTY_DATA_BUFFER).single().flatMap(body -> {
- String reqBody = body.toString(StandardCharsets.UTF_8);
- request.setBody(decrypt(reqBody, secretKey));
+ FizzServerHttpRequestDecorator request = (FizzServerHttpRequestDecorator) exchange.getRequest();
+ return request.getBody().defaultIfEmpty(NettyDataBufferUtils.EMPTY_DATA_BUFFER).single().flatMap(body -> {
+ /*String reqBody = body.toString(StandardCharsets.UTF_8);
+ request.setBody(decrypt(reqBody, secretKey));*/
- ServerHttpResponse original = exchange.getResponse();
- FizzServerHttpResponseDecorator fizzServerHttpResponseDecorator = new FizzServerHttpResponseDecorator(
- original) {
- @Override
- public Publisher extends DataBuffer> writeWith(DataBuffer remoteResponseBody) {
- String respBody = remoteResponseBody.toString(StandardCharsets.UTF_8);
- HttpHeaders headers = getDelegate().getHeaders();
- headers.setContentType(MediaType.TEXT_PLAIN);
- headers.remove(HttpHeaders.CONTENT_LENGTH);
- NettyDataBuffer from = NettyDataBufferUtils.from(encrypt(respBody, secretKey));
- return Mono.just(from);
- }
- };
- ServerWebExchange build = exchange.mutate().response(fizzServerHttpResponseDecorator).build();
- return FizzPluginFilterChain.next(build);
- });
+ String cryptoKey = systemConfig.fizzDedicatedLineClientRequestSecretkey();
+ if (body != NettyDataBufferUtils.EMPTY_DATA_BUFFER && StringUtils.isNotBlank(cryptoKey)) {
+ byte[] bodyBytes = request.getBodyBytes();
+ request.setBody(decrypt(bodyBytes, cryptoKey));
+ request.getHeaders().remove(HttpHeaders.CONTENT_LENGTH);
+ }
- } catch (Exception e) {
- log.error("{} {} Exception", traceId, DEDICATED_LINE_CODEC_PLUGIN_FILTER, e, LogService.BIZ_ID, traceId);
- String respJson = WebUtils.jsonRespBody(HttpStatus.INTERNAL_SERVER_ERROR.value(),
- HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase(), traceId);
- return WebUtils.response(exchange, HttpStatus.INTERNAL_SERVER_ERROR, null, respJson);
- }
- }
+ ServerHttpResponse original = exchange.getResponse();
+ FizzServerHttpResponseDecorator fizzServerHttpResponseDecorator = new FizzServerHttpResponseDecorator(original) {
+ @Override
+ public Publisher extends DataBuffer> writeWith(DataBuffer remoteResponseBody) {
+ /*String respBody = remoteResponseBody.toString(StandardCharsets.UTF_8);
+ HttpHeaders headers = getDelegate().getHeaders();
+ headers.setContentType(MediaType.TEXT_PLAIN);
+ headers.remove(HttpHeaders.CONTENT_LENGTH);
+ NettyDataBuffer from = NettyDataBufferUtils.from(encrypt(respBody, secretKey));
+ return Mono.just(from);*/
+ if (remoteResponseBody == NettyDataBufferUtils.EMPTY_DATA_BUFFER) {
+ return Mono.empty();
+ } else {
+ if (StringUtils.isNotBlank(cryptoKey)) {
+ getDelegate().getHeaders().remove(HttpHeaders.CONTENT_LENGTH);
+ byte[] bytes = remoteResponseBody.asByteBuffer().array();
+ NettyDataBuffer from = NettyDataBufferUtils.from(encrypt(bytes, cryptoKey));
+ return Mono.just(from);
+ } else {
+ return Mono.just(remoteResponseBody);
+ }
+ }
+ }
+ };
+ ServerWebExchange build = exchange.mutate().response(fizzServerHttpResponseDecorator).build();
+ return FizzPluginFilterChain.next(build);
+ });
- public String encrypt(String data, String secretKey) {
- if (StringUtils.isBlank(data)) {
- return data;
- }
- byte[] key = SecureUtil.decode(secretKey);
- SymmetricCrypto symmetric = new SymmetricCrypto(SymmetricAlgorithm.AES, key);
- return symmetric.encryptBase64(data);
- }
+ } catch (Exception e) {
+ log.error("{} {} Exception", traceId, DEDICATED_LINE_CODEC_PLUGIN_FILTER, LogService.BIZ_ID, traceId, e);
+ String respJson = WebUtils.jsonRespBody(HttpStatus.INTERNAL_SERVER_ERROR.value(),
+ HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase(), traceId);
+ return WebUtils.response(exchange, HttpStatus.INTERNAL_SERVER_ERROR, null, respJson);
+ }
+ }
- public String decrypt(String data, String secretKey) {
- if (StringUtils.isBlank(data)) {
- return data;
- }
- byte[] key = SecureUtil.decode(secretKey);
- SymmetricCrypto symmetric = new SymmetricCrypto(SymmetricAlgorithm.AES, key);
- return symmetric.decryptStr(data);
- }
+ public String encrypt(String data, String secretKey) {
+ if (StringUtils.isBlank(data)) {
+ return data;
+ }
+ byte[] key = SecureUtil.decode(secretKey);
+ SymmetricCrypto symmetric = new SymmetricCrypto(SymmetricAlgorithm.AES, key);
+ return symmetric.encryptBase64(data);
+ }
+ public byte[] encrypt(byte[] data, String secretKey) {
+ byte[] key = SecureUtil.decode(secretKey);
+ SymmetricCrypto symmetric = new SymmetricCrypto(SymmetricAlgorithm.AES, key);
+ return symmetric.encrypt(data);
+ }
+
+ public String decrypt(String data, String secretKey) {
+ if (StringUtils.isBlank(data)) {
+ return data;
+ }
+ byte[] key = SecureUtil.decode(secretKey);
+ SymmetricCrypto symmetric = new SymmetricCrypto(SymmetricAlgorithm.AES, key);
+ return symmetric.decryptStr(data);
+ }
+
+ public byte[] decrypt(byte[] data, String secretKey) {
+ byte[] key = SecureUtil.decode(secretKey);
+ SymmetricCrypto symmetric = new SymmetricCrypto(SymmetricAlgorithm.AES, key);
+ return symmetric.decrypt(data);
+ }
}
diff --git a/fizz-plugin/src/main/java/we/plugin/dedicatedline/pairing/DedicatedLinePairingPluginFilter.java b/fizz-plugin/src/main/java/we/plugin/dedicatedline/pairing/DedicatedLinePairingPluginFilter.java
index 6c1f1ec..106dd9e 100644
--- a/fizz-plugin/src/main/java/we/plugin/dedicatedline/pairing/DedicatedLinePairingPluginFilter.java
+++ b/fizz-plugin/src/main/java/we/plugin/dedicatedline/pairing/DedicatedLinePairingPluginFilter.java
@@ -17,10 +17,6 @@
package we.plugin.dedicatedline.pairing;
-import java.util.Map;
-
-import javax.annotation.Resource;
-
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -29,105 +25,101 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
-
import reactor.core.publisher.Mono;
import we.config.SystemConfig;
import we.dedicated_line.DedicatedLineService;
import we.flume.clients.log4j2appender.LogService;
import we.plugin.FizzPluginFilter;
import we.plugin.FizzPluginFilterChain;
-import we.plugin.auth.App;
-import we.plugin.auth.AppService;
import we.util.DigestUtils;
import we.util.ReactorUtils;
import we.util.WebUtils;
+import javax.annotation.Resource;
+import java.util.Map;
+
/**
- *
* @author Francis Dong
- *
*/
@ConditionalOnBean(DedicatedLineService.class)
@Component(DedicatedLinePairingPluginFilter.DEDICATED_LINE_PAIRING_PLUGIN_FILTER)
public class DedicatedLinePairingPluginFilter implements FizzPluginFilter {
- private static final Logger log = LoggerFactory.getLogger(DedicatedLinePairingPluginFilter.class);
+ private static final Logger log = LoggerFactory.getLogger(DedicatedLinePairingPluginFilter.class);
- public static final String DEDICATED_LINE_PAIRING_PLUGIN_FILTER = "dedicatedLinePairingPlugin";
+ public static final String DEDICATED_LINE_PAIRING_PLUGIN_FILTER = "dedicatedLinePairingPlugin";
- @Resource
- private SystemConfig systemConfig;
+ @Resource
+ private SystemConfig systemConfig;
- @Resource
- private DedicatedLineService dedicatedLineService;
+ @Resource
+ private DedicatedLineService dedicatedLineService;
- @SuppressWarnings({ "unchecked", "rawtypes" })
- @Override
- public Mono filter(ServerWebExchange exchange, Map config) {
- String traceId = WebUtils.getTraceId(exchange);
- try {
- LogService.setBizId(traceId);
- String dedicatedLineId = WebUtils.getDedicatedLineId(exchange);
- String secretKey = dedicatedLineService.getPairCodeSecretKey(dedicatedLineId);
- String ts = WebUtils.getDedicatedLineTimestamp(exchange);
- String sign = WebUtils.getDedicatedLineSign(exchange);
- if (validateSign(dedicatedLineId, ts, sign, secretKey)) {
- // Go to next plugin
- Mono next = FizzPluginFilterChain.next(exchange);
- return next.defaultIfEmpty(ReactorUtils.NULL).flatMap(nil -> {
- doAfter();
- return Mono.empty();
- });
- } else {
- // Auth failed
- ServerHttpResponse response = exchange.getResponse();
- response.setStatusCode(HttpStatus.UNAUTHORIZED);
- response.getHeaders().setCacheControl("no-store");
- response.getHeaders().setExpires(0);
- String respJson = WebUtils.jsonRespBody(HttpStatus.UNAUTHORIZED.value(),
- HttpStatus.UNAUTHORIZED.getReasonPhrase(), traceId);
- return WebUtils.response(exchange, HttpStatus.UNAUTHORIZED, null, respJson);
- }
- } catch (Exception e) {
- log.error("{} {} Exception", traceId, DEDICATED_LINE_PAIRING_PLUGIN_FILTER, e, LogService.BIZ_ID, traceId);
- String respJson = WebUtils.jsonRespBody(HttpStatus.INTERNAL_SERVER_ERROR.value(),
- HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase(), traceId);
- return WebUtils.response(exchange, HttpStatus.INTERNAL_SERVER_ERROR, null, respJson);
- }
- }
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ @Override
+ public Mono filter(ServerWebExchange exchange, Map config) {
+ String traceId = WebUtils.getTraceId(exchange);
+ try {
+ LogService.setBizId(traceId);
+ String dedicatedLineId = WebUtils.getDedicatedLineId(exchange);
+ String secretKey = dedicatedLineService.getPairCodeSecretKey(dedicatedLineId);
+ String ts = WebUtils.getDedicatedLineTimestamp(exchange);
+ String sign = WebUtils.getDedicatedLineSign(exchange);
+ if (validateSign(dedicatedLineId, ts, sign, secretKey)) {
+ // Go to next plugin
+ Mono next = FizzPluginFilterChain.next(exchange);
+ return next.defaultIfEmpty(ReactorUtils.NULL).flatMap(nil -> {
+ doAfter();
+ return Mono.empty();
+ });
+ } else {
+ // Auth failed
+ ServerHttpResponse response = exchange.getResponse();
+ response.setStatusCode(HttpStatus.UNAUTHORIZED);
+ response.getHeaders().setCacheControl("no-store");
+ response.getHeaders().setExpires(0);
+ String respJson = WebUtils.jsonRespBody(HttpStatus.UNAUTHORIZED.value(),
+ HttpStatus.UNAUTHORIZED.getReasonPhrase(), traceId);
+ return WebUtils.response(exchange, HttpStatus.UNAUTHORIZED, null, respJson);
+ }
+ } catch (Exception e) {
+ log.error("{} {} Exception", traceId, DEDICATED_LINE_PAIRING_PLUGIN_FILTER, LogService.BIZ_ID, traceId, e);
+ String respJson = WebUtils.jsonRespBody(HttpStatus.INTERNAL_SERVER_ERROR.value(),
+ HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase(), traceId);
+ return WebUtils.response(exchange, HttpStatus.INTERNAL_SERVER_ERROR, null, respJson);
+ }
+ }
- private boolean validateSign(String dedicatedLineId, String ts, String sign, String secretkey) {
- if (StringUtils.isBlank(dedicatedLineId) || StringUtils.isBlank(ts) || StringUtils.isBlank(sign)
- || StringUtils.isBlank(secretkey)) {
- return false;
- }
+ private boolean validateSign(String dedicatedLineId, String ts, String sign, String secretkey) {
+ if (StringUtils.isBlank(dedicatedLineId) || StringUtils.isBlank(ts) || StringUtils.isBlank(sign)
+ || StringUtils.isBlank(secretkey)) {
+ return false;
+ }
- // SHA256(dedicatedLineId+_+ts+_+secretkey)
- String data = dedicatedLineId + "_" + ts + "_" + secretkey;
- if (!DigestUtils.sha256Hex(data).equals(sign)) {
- return false;
- }
+ // SHA256(dedicatedLineId+_+ts+_+secretkey)
+ String data = dedicatedLineId + "_" + ts + "_" + secretkey;
+ if (!DigestUtils.sha256Hex(data).equals(sign)) {
+ return false;
+ }
- // validate timestamp
- long t = 0;
- try {
- t = Long.valueOf(ts).longValue();
- } catch (Exception e) {
- log.warn("invalid timestamp: {}", ts);
- return false;
- }
- long now = System.currentTimeMillis();
- long offset = 5 * 60 * 1000;
- if (t < now - offset || t > now + offset) {
- log.warn("timestamp expired: {}", ts);
- return false;
- }
+ // validate timestamp
+ long t = 0;
+ try {
+ t = Long.valueOf(ts).longValue();
+ } catch (Exception e) {
+ log.warn("invalid timestamp: {}", ts);
+ return false;
+ }
+ long now = System.currentTimeMillis();
+ long offset = 5 * 60 * 1000;
+ if (t < now - offset || t > now + offset) {
+ log.warn("timestamp expired: {}", ts);
+ return false;
+ }
- return true;
- }
-
- public void doAfter() {
-
- }
+ return true;
+ }
+ public void doAfter() {
+ }
}
diff --git a/pom.xml b/pom.xml
index 0810719..2432bf7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,7 +22,7 @@
0.8.2
0.9.11
2.11.1
- 2.0.45.Final
+ 2.0.46.Final
2.2.9.RELEASE
1.7.1