diff --git a/fizz-plugin/pom.xml b/fizz-plugin/pom.xml index 5f72f15..ed5b322 100644 --- a/fizz-plugin/pom.xml +++ b/fizz-plugin/pom.xml @@ -258,6 +258,11 @@ commons-codec commons-codec + + + cn.hutool + hutool-crypto + diff --git a/fizz-plugin/src/main/java/we/plugin/apidoc/ApiDocAuthPluginFilter.java b/fizz-plugin/src/main/java/we/plugin/dedicatedline/auth/DedicatedLineApiAuthPluginFilter.java similarity index 85% rename from fizz-plugin/src/main/java/we/plugin/apidoc/ApiDocAuthPluginFilter.java rename to fizz-plugin/src/main/java/we/plugin/dedicatedline/auth/DedicatedLineApiAuthPluginFilter.java index 824cb96..db4ec69 100644 --- a/fizz-plugin/src/main/java/we/plugin/apidoc/ApiDocAuthPluginFilter.java +++ b/fizz-plugin/src/main/java/we/plugin/dedicatedline/auth/DedicatedLineApiAuthPluginFilter.java @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package we.plugin.apidoc; +package we.plugin.dedicatedline.auth; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,13 +41,12 @@ import java.util.Map; * @author Francis Dong * */ -@ConditionalOnProperty(name = SystemConfig.FIZZ_API_PAIRING_SERVER_ENABLE, havingValue = "true") -@Component(ApiDocAuthPluginFilter.API_DOC_AUTH_PLUGIN_FILTER) -public class ApiDocAuthPluginFilter implements FizzPluginFilter { +@Component(DedicatedLineApiAuthPluginFilter.DEDICATED_LINE_API_AUTH_PLUGIN_FILTER) +public class DedicatedLineApiAuthPluginFilter implements FizzPluginFilter { - private static final Logger log = LoggerFactory.getLogger(ApiDocAuthPluginFilter.class); + private static final Logger log = LoggerFactory.getLogger(DedicatedLineApiAuthPluginFilter.class); - public static final String API_DOC_AUTH_PLUGIN_FILTER = "apiDocAuthPlugin"; + public static final String DEDICATED_LINE_API_AUTH_PLUGIN_FILTER = "dedicatedLineCodecPlugin"; @Resource private ApiPairingDocSetService apiPairingDocSetService; @@ -79,7 +78,7 @@ public class ApiDocAuthPluginFilter implements FizzPluginFilter { return WebUtils.response(exchange, HttpStatus.UNAUTHORIZED, null, respJson); } } catch (Exception e) { - log.error("{} {} exception", traceId, API_DOC_AUTH_PLUGIN_FILTER, e); + log.error("{} {} exception", traceId, DEDICATED_LINE_API_AUTH_PLUGIN_FILTER, 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 new file mode 100644 index 0000000..d1946e3 --- /dev/null +++ b/fizz-plugin/src/main/java/we/plugin/dedicatedline/codec/DedicatedLineCodecPluginFilter.java @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2021 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.plugin.dedicatedline.codec; + +import java.nio.charset.StandardCharsets; +import java.util.Map; + +import javax.annotation.Resource; + +import org.apache.commons.lang3.StringUtils; +import org.reactivestreams.Publisher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.core.io.buffer.NettyDataBuffer; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +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.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.NettyDataBufferUtils; +import we.util.WebUtils; + +/** + * + * @author Francis Dong + * + */ +@Component(DedicatedLineCodecPluginFilter.DEDICATED_LINE_CODEC_PLUGIN_FILTER) +public class DedicatedLineCodecPluginFilter extends RequestBodyPlugin { + + private static final Logger log = LoggerFactory.getLogger(DedicatedLineCodecPluginFilter.class); + + public static final String DEDICATED_LINE_CODEC_PLUGIN_FILTER = "dedicatedLineCodecPlugin"; + + @Resource + private SystemConfig systemConfig; + + @Resource + private AppService appService; + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public Mono doFilter(ServerWebExchange exchange, Map config) { + String traceId = WebUtils.getTraceId(exchange); + try { + LogService.setBizId(traceId); + String appid = WebUtils.getAppId(exchange); + App app = appService.getApp(appid); + + String secretKey = "1gG1dVcEaQz8JyifTHeEnQ=="; + + 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 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); + }); + + } 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); + } + } + + 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 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); + } + +} diff --git a/fizz-plugin/src/main/java/we/plugin/pairing/ApiPairingPluginFilter.java b/fizz-plugin/src/main/java/we/plugin/dedicatedline/pairing/FizzPairingPluginFilter.java similarity index 89% rename from fizz-plugin/src/main/java/we/plugin/pairing/ApiPairingPluginFilter.java rename to fizz-plugin/src/main/java/we/plugin/dedicatedline/pairing/FizzPairingPluginFilter.java index 673ac46..21a953d 100644 --- a/fizz-plugin/src/main/java/we/plugin/pairing/ApiPairingPluginFilter.java +++ b/fizz-plugin/src/main/java/we/plugin/dedicatedline/pairing/FizzPairingPluginFilter.java @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package we.plugin.pairing; +package we.plugin.dedicatedline.pairing; import java.util.Map; @@ -45,12 +45,12 @@ import we.util.WebUtils; * @author Francis Dong * */ -@Component(ApiPairingPluginFilter.API_PAIRING_PLUGIN_FILTER) -public class ApiPairingPluginFilter implements FizzPluginFilter { +@Component(FizzPairingPluginFilter.FIZZ_PAIRING_PLUGIN_FILTER) +public class FizzPairingPluginFilter implements FizzPluginFilter { - private static final Logger log = LoggerFactory.getLogger(ApiPairingPluginFilter.class); + private static final Logger log = LoggerFactory.getLogger(FizzPairingPluginFilter.class); - public static final String API_PAIRING_PLUGIN_FILTER = "apiPairingPlugin"; + public static final String FIZZ_PAIRING_PLUGIN_FILTER = "fizzPairingPlugin"; @Resource private SystemConfig systemConfig; @@ -86,7 +86,7 @@ public class ApiPairingPluginFilter implements FizzPluginFilter { return WebUtils.response(exchange, HttpStatus.UNAUTHORIZED, null, respJson); } } catch (Exception e) { - log.error("{} {} Exception", traceId, API_PAIRING_PLUGIN_FILTER, e, LogService.BIZ_ID, traceId); + log.error("{} {} Exception", traceId, FIZZ_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); diff --git a/pom.xml b/pom.xml index b52edda..ae33119 100644 --- a/pom.xml +++ b/pom.xml @@ -433,6 +433,13 @@ netty-tcnative-boringssl-static ${netty-tcnative.version} + + + cn.hutool + hutool-crypto + 5.7.16 + +