在一些对安全要求很高的系统,需要对数据进行加密传输,我们可以采用在网关加密解密数据传输提高系统安全性,加密解密算法使用rsa(相对性能影响较小),java代码如下importcn。hutool。crypto。SecureUtil;importcn。hutool。crypto。asymmetric。KeyType;importcn。hutool。crypto。asymmetric。RSA;importcom。google。common。base。Joiner;importio。netty。buffer。ByteBufAllocator;importlombok。extern。slf4j。Slf4j;importorg。apache。commons。compress。utils。Lists;importorg。apache。commons。lang3。StringUtils;importorg。reactivestreams。Publisher;importorg。springframework。cloud。context。config。annotation。RefreshScope;importorg。springframework。cloud。gateway。filter。GatewayFilterChain;importorg。springframework。cloud。gateway。filter。GlobalFilter;importorg。springframework。core。Ordered;importorg。springframework。core。io。buffer。DataBuffer;importorg。springframework。core。io。buffer。DataBufferFactory;importorg。springframework。core。io。buffer。DataBufferUtils;importorg。springframework。core。io。buffer。NettyDataBufferFactory;importorg。springframework。http。HttpMethod;importorg。springframework。http。HttpStatus;importorg。springframework。http。MediaType;importorg。springframework。http。server。reactive。ServerHttpRequest;importorg。springframework。http。server。reactive。ServerHttpRequestDecorator;importorg。springframework。http。server。reactive。ServerHttpResponse;importorg。springframework。http。server。reactive。ServerHttpResponseDecorator;importorg。springframework。stereotype。Component;importorg。springframework。web。server。ServerWebExchange;importreactor。core。publisher。Flux;importreactor。core。publisher。Mono;importjava。net。URI;importjava。nio。CharBuffer;importjava。nio。charset。Charset;importjava。nio。charset。StandardCharsets;importjava。util。List;importjava。util。concurrent。atomic。AtomicReference;importstaticorg。springframework。cloud。gateway。support。ServerWebExchangeUtils。ORIGINALRESPONSECONTENTTYPEATTR;ClassNameAppFilterDescriptionTODOAuthorljqDate2022121316:16Version1。0Slf4jRefreshScopeComponentpublicclassAppFilterimplementsGlobalFilter,Ordered{privatestaticJoinerjoinerJoiner。on();OverridepublicMonoVoidfilter(ServerWebExchangeexchange,GatewayFilterChainchain){如果存在appId走应用认证接口ServerHttpRequestrequestexchange。getRequest();StringappIdrequest。getHeaders()。getFirst(appId);if(StringUtils。isNotBlank(appId)){if(exchange。getRequest()。getMethod()。equals(HttpMethod。POST)){StringbodyStrgetBodyStr(exchange。getRequest()。getBody());log。info(加密原始数据bodyStr);重新封装请求因为请求体内容已被消费,需要重新写入URIurirequest。getURI();requestrequest。mutate()。uri(uri)。build();这块需要掉用微服务进行应用权限校验并返回应用公私钥这里使用hutu工具包对数据进行rsa加解密startStringprivateKey30820155020100300d06092a864886f70d01010105000482013f3082013b020100024100b9c7d70130df32ff4f41f79390fc085439e917a632b2707c0d3d4c8da0cedc22e55d66ddbe59287b16aa63ff3a98d23e3938da0ceabac4167204e09a3a0cd88f020301000102401f5ae821ce52cd73a3b7d98631612832b6f76d4362a9152d0abafed1a4836549c042700fc26b750a460c999c9a0107aec4cdfecde897606dcc56bb653aee1a89022100f773cf5f947e4eb442b8a2ba42929a557e2b6c48869347296fe6e5a5c7e12513022100c032ac9e7c2ca7ca817bdd8626fe25f427188c10bc42206fd3605764f767ba15022100f0653ded29219bec5b756c016f736523f132d63b8f21bd5c702deca4258e80a9022043e3625fd4c2bd3de580c81db3b63fd7bedb87d5fd796a15b5d728e78c104285022100879796fca38aadf54a0dd90959d1eef452fffe504d73dbaff887f5089e36cd19;StringpublicKey305c300d06092a864886f70d0101010500034b003048024100b9c7d70130df32ff4f41f79390fc085439e917a632b2707c0d3d4c8da0cedc22e55d66ddbe59287b16aa63ff3a98d23e3938da0ceabac4167204e09a3a0cd88f0203010001;RSArsaSecureUtil。rsa(privateKey,publicKey);bodyStrrsa。decryptStr(bodyStr,KeyType。PrivateKey);log。info(解密数据:bodyStr);这块需要掉用微服务进行应用权限校验并返回应用公私钥这里使用hutu工具包对数据进行rsa加解密end将解密数据封装向下传递DataBufferbodyDataBufferstringBuffer(bodyStr);FluxDataBufferbodyFluxFlux。just(bodyDataBuffer);requestnewServerHttpRequestDecorator(request){OverridepublicFluxDataBuffergetBody(){returnbodyFlux;}};可以选择对返回体也进行加密ResBodyEncryptDecoratorresponseDecoratornewResBodyEncryptDecorator(exchange。getResponse(),exchange。getAttribute(ORIGINALRESPONSECONTENTTYPEATTR),rsa);ServerHttpRequestnewRequestrequest。mutate()。build();returnchain。filter(exchange。mutate()。request(newRequest)。response(responseDecorator)。build());}else{可以将get请求也设置特定的参数读取加解密可以照着post请求做returnAppIdInvalid(exchange);}}else{returnAppIdInvalid(exchange);}}publicstaticclassResBodyEncryptDecoratorextendsServerHttpResponseDecorator{privateDataBufferFactorybufferFactory;privateStringcontentType;privateRSArsa;publicResBodyEncryptDecorator(ServerHttpResponsedelegate,StringcontentType,RSArsa){super(delegate);this。contentTypecontentType;this。bufferFactorydelegate。bufferFactory();this。rsarsa;}OverridepublicMonoVoidwriteWith(Publisherlt;?extendsDataBufferbody){log。info(得到响应体);if(getStatusCode()。equals(HttpStatus。OK)bodyinstanceofFlux){获取响应ContentType记录JSON格式数据的响应体if(!StringUtils。isEmpty(contentType)contentType。contains(MediaType。APPLICATIONJSONVALUE)){Fluxlt;?extendsDataBufferfluxBodyFlux。from(body);解决返回体分段传输returnsuper。writeWith(fluxBody。buffer()。map(dataBuffers{ListStringlistLists。newArrayList();dataBuffers。forEach(dataBuffer{byte〔〕contentnewbyte〔dataBuffer。readableByteCount()〕;dataBuffer。read(content);DataBufferUtils。release(dataBuffer);list。add(newString(content,Charset。forName(UTF8)));});StringresponseDatajoiner。join(list);log。info(得到响应体内容:{},responseData。replaceAll(,)。replaceAll(,));responseDatarsa。encryptBase64(responseData,KeyType。PublicKey);returnbufferFactory。wrap(responseData。getBytes());}));}}returnsuper。writeWith(body);}}token无效,消息返回paramexchangereturnprivateMonoVoidAppIdInvalid(ServerWebExchangeexchange){ServerHttpResponseresponseexchange。getResponse();byte〔〕bits{result:1,message:应用不存在,data:null}。getBytes(StandardCharsets。UTF8);DataBufferbufferresponse。bufferFactory()。wrap(bits);response。setStatusCode(HttpStatus。UNAUTHORIZED);指定编码,否则在浏览器中会中文乱码response。getHeaders()。add(ContentType,textplain;charsetUTF8);returnresponse。writeWith(Mono。just(buffer));}获取请求体内容parambodyreturnprivateStringgetBodyStr(FluxDataBufferbody){AtomicReferenceStringbodyRefnewAtomicReference();body。subscribe(buffer{CharBuffercharBufferStandardCharsets。UTF8。decode(buffer。asByteBuffer());DataBufferUtils。release(buffer);bodyRef。set(charBuffer。toString());log。info(charBuffer。toString());});获取requestbodyreturnbodyRef。get();}privateDataBufferstringBuffer(Stringvalue){byte〔〕bytesvalue。getBytes(StandardCharsets。UTF8);NettyDataBufferFactorynettyDataBufferFactorynewNettyDataBufferFactory(ByteBufAllocator。DEFAULT);DataBufferbuffernettyDataBufferFactory。allocateBuffer(bytes。length);buffer。write(bytes);returnbuffer;}publicstaticvoidmain(String〔〕args){StringprivateKey30820155020100300d06092a864886f70d01010105000482013f3082013b020100024100b9c7d70130df32ff4f41f79390fc085439e917a632b2707c0d3d4c8da0cedc22e55d66ddbe59287b16aa63ff3a98d23e3938da0ceabac4167204e09a3a0cd88f020301000102401f5ae821ce52cd73a3b7d98631612832b6f76d4362a9152d0abafed1a4836549c042700fc26b750a460c999c9a0107aec4cdfecde897606dcc56bb653aee1a89022100f773cf5f947e4eb442b8a2ba42929a557e2b6c48869347296fe6e5a5c7e12513022100c032ac9e7c2ca7ca817bdd8626fe25f427188c10bc42206fd3605764f767ba15022100f0653ded29219bec5b756c016f736523f132d63b8f21bd5c702deca4258e80a9022043e3625fd4c2bd3de580c81db3b63fd7bedb87d5fd796a15b5d728e78c104285022100879796fca38aadf54a0dd90959d1eef452fffe504d73dbaff887f5089e36cd19;StringpublicKey305c300d06092a864886f70d0101010500034b003048024100b9c7d70130df32ff4f41f79390fc085439e917a632b2707c0d3d4c8da0cedc22e55d66ddbe59287b16aa63ff3a98d23e3938da0ceabac4167204e09a3a0cd88f0203010001;RSArsaSecureUtil。rsa(privateKey,publicKey);Stringdata{current:1,size:20,param:{afterSale:Y,commitTimeStart:2011111100:00:00}};Stringencryptrsa。encryptBase64(data,KeyType。PrivateKey);Stringdecyptrsa。decryptStr(encrypt,KeyType。PublicKey);System。out。println(encrypt);System。out。println(decypt);encryptrsa。encryptBase64(data,KeyType。PublicKey);decyptrsa。decryptStr(encrypt,KeyType。PrivateKey);System。out。println(encrypt);System。out。println(decypt);}OverridepublicintgetOrder(){return2;}} 遇到的问题: 1有可能无法获取到请求体里面的内容可以参考https:zhuanlan。zhihu。comp471402045 效果: postman请求 服务器日志