范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

springgateway实现接口数据加密传输

  在一些对安全要求很高的系统,需要对数据进行加密传输,我们可以采用在网关加密解密数据传输提高系统安全性,加密解密算法使用rsa(相对性能影响较小),java代码如下import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.asymmetric.KeyType; import cn.hutool.crypto.asymmetric.RSA; import com.google.common.base.Joiner; import io.netty.buffer.ByteBufAllocator; import lombok.extern.slf4j.Slf4j; import org.apache.commons.compress.utils.Lists; import org.apache.commons.lang3.StringUtils; import org.reactivestreams.Publisher; import org.springframework.cloud.context.config.annotation.RefreshScope; 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.DataBufferFactory; import org.springframework.core.io.buffer.DataBufferUtils; import org.springframework.core.io.buffer.NettyDataBufferFactory; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpRequestDecorator; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.http.server.reactive.ServerHttpResponseDecorator; 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.nio.CharBuffer; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.concurrent.atomic.AtomicReference;  import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR;  /**  * @ClassName AppFilter  * @Description TODO  * @Author ljq  * @Date 2022/12/13 16:16  * @Version 1.0  */ @Slf4j @RefreshScope @Component public class AppFilter implements GlobalFilter, Ordered {      private static Joiner joiner = Joiner.on("");      @Override     public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {         //如果存在appId 走应用认证接口         ServerHttpRequest request = exchange.getRequest();         String appId = request.getHeaders().getFirst("appId");         if(StringUtils.isNotBlank(appId)){             if (exchange.getRequest().getMethod().equals(HttpMethod.POST)) {                 String bodyStr = getBodyStr(exchange.getRequest().getBody());                 log.info("加密原始数据"+bodyStr);                 //重新封装请求 因为请求体内容已被消费,需要重新写入                 URI uri = request.getURI();                 request = request.mutate().uri(uri).build();                  //这块需要掉用微服务进行应用权限校验 并返回应用公私钥 这里使用hutu工具包 对数据进行rsa加解密 start                 String privateKey = "30820155020100300d06092a864886f70d01010105000482013f3082013b020100024100b9c7d70130df32ff4f41f79390fc085439e917a632b2707c0d3d4c8da0cedc22e55d66ddbe59287b16aa63ff3a98d23e3938da0ceabac4167204e09a3a0cd88f020301000102401f5ae821ce52cd73a3b7d98631612832b6f76d4362a9152d0abafed1a4836549c042700fc26b750a460c999c9a0107aec4cdfecde897606dcc56bb653aee1a89022100f773cf5f947e4eb442b8a2ba42929a557e2b6c48869347296fe6e5a5c7e12513022100c032ac9e7c2ca7ca817bdd8626fe25f427188c10bc42206fd3605764f767ba15022100f0653ded29219bec5b756c016f736523f132d63b8f21bd5c702deca4258e80a9022043e3625fd4c2bd3de580c81db3b63fd7bedb87d5fd796a15b5d728e78c104285022100879796fca38aadf54a0dd90959d1eef452fffe504d73dbaff887f5089e36cd19";                 String publicKey = "305c300d06092a864886f70d0101010500034b003048024100b9c7d70130df32ff4f41f79390fc085439e917a632b2707c0d3d4c8da0cedc22e55d66ddbe59287b16aa63ff3a98d23e3938da0ceabac4167204e09a3a0cd88f0203010001";                 RSA rsa = SecureUtil.rsa(privateKey,publicKey);                 bodyStr = rsa.decryptStr(bodyStr, KeyType.PrivateKey);                 log.info("解密数据:"+bodyStr);                 //这块需要掉用微服务进行应用权限校验 并返回应用公私钥 这里使用hutu工具包 对数据进行rsa加解密 end                 //将解密数据封装向下传递                 DataBuffer bodyDataBuffer = stringBuffer(bodyStr);                  Flux bodyFlux = Flux.just(bodyDataBuffer);                 request = new ServerHttpRequestDecorator(request) {                     @Override                     public Flux getBody() {                         return bodyFlux;                     }                 };                  //可以选择对返回体也进行加密                 ResBodyEncryptDecorator responseDecorator = new ResBodyEncryptDecorator(exchange.getResponse(),exchange.getAttribute(ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR),rsa);                  ServerHttpRequest newRequest = request.mutate().build();                 return chain.filter(exchange.mutate().request(newRequest).response(responseDecorator).build());             }else{                 //可以将get请求也设置特定的参数读取加解密 可以照着post请求做                 return AppIdInvalid(exchange);             }         }else{             return AppIdInvalid(exchange);         }      }      public static class ResBodyEncryptDecorator extends ServerHttpResponseDecorator{          private DataBufferFactory bufferFactory;          private String contentType;          private RSA rsa;          public ResBodyEncryptDecorator(ServerHttpResponse delegate,String contentType,RSA rsa) {             super(delegate);             this.contentType = contentType;             this.bufferFactory = delegate.bufferFactory();             this.rsa = rsa;         }          @Override         public Mono writeWith(Publisher<? extends DataBuffer> body) {             log.info("得到响应体");             if (getStatusCode().equals(HttpStatus.OK) && body instanceof Flux) {                 // 获取响应 ContentType                 // 记录 JSON 格式数据的响应体                 if (!StringUtils.isEmpty(contentType) && contentType.contains(MediaType.APPLICATION_JSON_VALUE)) {                     Flux<? extends DataBuffer> fluxBody = Flux.from(body);                     // 解决返回体分段传输                     return super.writeWith(fluxBody.buffer().map(dataBuffers -> {                         List list = Lists.newArrayList();                         dataBuffers.forEach(dataBuffer -> {                             byte[] content = new byte[dataBuffer.readableByteCount()];                             dataBuffer.read(content);                             DataBufferUtils.release(dataBuffer);                             list.add(new String(content, Charset.forName("UTF-8")));                         });                         String responseData = joiner.join(list);                         log.info("得到响应体内容:{}", responseData.replaceAll(" ","").replaceAll("	",""));                         responseData = rsa.encryptBase64(responseData, KeyType.PublicKey);                         return bufferFactory.wrap(responseData.getBytes());                     }));                 }             }             return super.writeWith(body);         }     }      /**      * token 无效,消息返回      * @param exchange      * @return      */     private Mono AppIdInvalid(ServerWebExchange exchange) {         ServerHttpResponse response = exchange.getResponse();         byte[] bits = "{"result":"-1","message":"应用不存在","data":null}".getBytes(StandardCharsets.UTF_8);         DataBuffer buffer = response.bufferFactory().wrap(bits);         response.setStatusCode(HttpStatus.UNAUTHORIZED);         //指定编码,否则在浏览器中会中文乱码         response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");         return response.writeWith(Mono.just(buffer));     }       /**      * 获取请求体内容      * @param body      * @return      */     private String getBodyStr(Flux body) {         AtomicReference bodyRef = new AtomicReference<>();         body.subscribe(buffer -> {             CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());             DataBufferUtils.release(buffer);             bodyRef.set(charBuffer.toString());             log.info(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;     }      public static void main(String[] args) {         String privateKey = "30820155020100300d06092a864886f70d01010105000482013f3082013b020100024100b9c7d70130df32ff4f41f79390fc085439e917a632b2707c0d3d4c8da0cedc22e55d66ddbe59287b16aa63ff3a98d23e3938da0ceabac4167204e09a3a0cd88f020301000102401f5ae821ce52cd73a3b7d98631612832b6f76d4362a9152d0abafed1a4836549c042700fc26b750a460c999c9a0107aec4cdfecde897606dcc56bb653aee1a89022100f773cf5f947e4eb442b8a2ba42929a557e2b6c48869347296fe6e5a5c7e12513022100c032ac9e7c2ca7ca817bdd8626fe25f427188c10bc42206fd3605764f767ba15022100f0653ded29219bec5b756c016f736523f132d63b8f21bd5c702deca4258e80a9022043e3625fd4c2bd3de580c81db3b63fd7bedb87d5fd796a15b5d728e78c104285022100879796fca38aadf54a0dd90959d1eef452fffe504d73dbaff887f5089e36cd19";         String publicKey = "305c300d06092a864886f70d0101010500034b003048024100b9c7d70130df32ff4f41f79390fc085439e917a632b2707c0d3d4c8da0cedc22e55d66ddbe59287b16aa63ff3a98d23e3938da0ceabac4167204e09a3a0cd88f0203010001";         RSA rsa = SecureUtil.rsa(privateKey,publicKey);         String data = "{ " +                 "    "current":1, " +                 "    "size":20, " +                 "    "param":{ " +                 "        "afterSale":"Y", " +                 "        "commitTimeStart":"2011-11-11 00:00:00" " +                 "    } " +                 "}";         String encrypt = rsa.encryptBase64(data, KeyType.PrivateKey);         String decypt = rsa.decryptStr(encrypt, KeyType.PublicKey);         System.out.println(encrypt);         System.out.println(decypt);         encrypt = rsa.encryptBase64(data, KeyType.PublicKey);         decypt = rsa.decryptStr(encrypt, KeyType.PrivateKey);         System.out.println(encrypt);         System.out.println(decypt);     }      @Override     public int getOrder() {         return -2;     } }
  遇到的问题:
  1 有可能无法获取到请求体里面的内容可以参考 https://zhuanlan.zhihu.com/p/471402045
  效果:
  postman请求
  服务器日志

祝贺!灵丘红石塄乡上榜啦黄河新闻网大同讯(记者吴星)近日,文化和旅游部第四批全国乡村旅游重点村名单和第二批全国乡村旅游重点镇(乡)名单出炉,大同市灵丘县红石塄乡上榜。红石塄乡位于灵丘县东南部,西依太白巍山巨变丁香湖2005年前丁香湖地区违法挖沙,使这里坑塘连片。丁香湖,曾经是沈阳的母亲河浑河的古河道。上世纪末,因违法挖沙行为泛滥,这里坑塘连片,破烂不堪,是当时沈阳的龙须沟。2002年,丁香湖70后的女人依然美丽一晃都五十了,对我来说,年龄其实真的不是问题,很多人到了五十以后,就觉得打扮已经没有那么重要了。退休了,在家带孙子,就不再注重自己的外形。任由自己放纵,身材变了,面孔也苍老了,最后世界多么美丽秋日生活打卡季人生在世,不会一直顺风顺水,总会坎坎坷坷,会有一些不如意,会有烦恼郁闷忧愁和不愉快。这个时候,听一曲轻快悦耳的音乐,看着和音乐一起出现的视频中的美景,心情会豁然开朗,奋斗的青春最美丽奋斗的青春,是长风破浪会有时,直挂云帆济沧海的豪情壮志奋斗的青春,是千磨万击还坚劲,任尔东西南北风的坚韧顽强奋斗的青春,是仰天大笑出门去,我辈岂是蓬蒿人的自信难掩奋斗的青春,是雄关张柏芝被周星驰捧红,让陈冠希毁掉青春,三胎父亲至今不敢露面文娱情故纵编辑娱情故纵前言如果提起张柏芝这位争议颇多的女星时,不知道网友们首先会想到什么?这么多年以来每当张柏芝出现的时候,关于她身上的标签和争议几乎从来都不少。从当年出道第一部戏齐女宣姜,美丽也是一种罪恶陌上人如玉,公子世无双。每个人都渴望俊美的容颜,儒雅的外表。渴望翩翩公子,玉树临风,清扬婉兮,遗世独立。无论这样的容貌能否为人生带来益处,都是一道靓丽的风景,令人愉悦,赏心悦目。目吾辈青年,生于青春吾愿吾亲爱之青年,生于青春死于青春,生于少年死于少年也。题记吾辈青年作为新时代青年,当担起历史责任,让青春在新时代改革开放的广阔天地中绽放,让人生在实现中国梦的奋斗追逐中展现出勇敢约网友见面的情景永远刻进记忆里我辜负了一个美丽的女孩子上篇十二年前那时QQ盛行,经常去泡网吧。我从零六年开始接触电脑,只是看电影,听歌,不会聊天,因为不会打字,汉语拼音也不会。很多同年人都在沉迷游戏,昼夜乐在其中,废寢忘食,不去工作,红尘心若美丽,你我皆可成诗很想为你写首小诗把心尖的喜悦给你可岁月湮灭了太多的情怀身外物都给你我更想遁入虚空感知世界又不干涉万物运行打坐闭关忘掉空间时间风花雪月与禅定相左世间世俗入乡随俗男欢女爱就得调情颇多生3700万,再见篮网!杜兰特逐渐不耐烦,一手好牌彻底被你自己浪费12886,谁能想到,欧文被禁赛,西蒙斯高挂免战牌,小库里伤病反复,处于动荡混乱当中的篮网,可以在奇才的主场打出如此酣畅淋漓的比赛?全场比赛,杜兰特打得十分轻松,他在33分钟的出场
身体上自带的不用花钱的止咳穴,调理咳嗽穴位汇总,赶紧收藏咳嗽虽然是肺病,但五脏六腑的病变均能引发咳嗽,并不是只有肺脏。下面我就根据咳嗽的不同症状特点,为大家有针对性地介绍一些特效的穴位1咳喘穴快速止咳咳喘穴快速取穴张开手掌,小拇指无名指肺部的这些表现!快来对照看看你属于哪一种肺有寒原因1外邪受寒,如淋雨2过食寒凉(凉菜海鲜等)3体虚肺火大原因1过吃火锅,辣椒,烧烤等上火之物2受外邪感染导致肺气虚原因1脾虚运化差,无法转化为肺气2透支过度,比如常年高强度长寿秘密有3!除了饮食运动外,第三个很关键!少有人做到养生抗衰老长寿是自古以来的热门话题,为此神话故事中古人远赴东海求仙药殚精竭虑炼制仙丹,现今也有人妄想通过定期输入新鲜血液基因编辑来永葆青春,但都是不切实际的。王药师搜集研究了100SOR索尔想要去黑头,就请别乱用鼻贴去除黑头都有些什么方法?据SOR索尔护肤小编了解,日常中最常见且常用的就是一些鼻贴产品,虽然可以快速清晰地去除黑头,然而在快速效果产品后面,鼻贴对鼻子的伤害也不容忽视。我们在使用鼻音乐才子郭峰还没成家就老了,60岁婚姻成难题2022年2月4日,大众熟知的歌曲让世界充满爱,唱响在北京冬奥会的开幕式上。这首歌第一次走红,是因为1998年抗洪公益群星大合唱。但其实它是一首诞生于1986年的歌曲,当时恰逢国际奥运冠军高敏扫雪太卖力!用扫把铲车顶积雪,身后豪宅分外惹眼近日,跳水女皇高敏在自己的社交媒体平台发布一则扫雪视频,活力满满的她却因为穿着引起了网友们的争议。视频中,高敏包裹严实,打扮很是保暖。只见她身穿一件厚厚的黑色羽绒服,穿着雪地靴,素库里33分勇士104119不敌快船快船主场119104轻取勇士。鲁尼上来扣篮,快船则回敬一波90。库里中距离抛投,汤普森三分,此后库里大爆发连中4记三分,他在前7分钟6投6中得到16分,帮助勇士2623领先。快船这正式离队!广东宏远国字号后卫被迫走人,杜锋开始调整争冠阵容作为CBA青训培养做成功的球队,广东宏远最近几个赛季也是迎来了低谷期,除了徐杰胡明轩杜润旺这批球员能够进入轮换之外,刘权标马力克张昊都还没有达到教练组的预期。在年轻球员中,只有赵锦央视主持人陈滢解说翻车?同样是带情绪解说,王濛的处理更恰当都是个性鲜明的解说,王濛被夸上热搜,陈滢却被质疑像粉丝捧偶像引言。王濛因为短道速滑的一场场解说,王濛成功登上多个热搜,继世界冠军奥运冠军之外,王濛成功解锁了新身份体育mcn机构创始感恩比赛?韩国运动员回应打扫领奖台韩媒力挺网友啼笑皆非您好,本文阅读大约需要两分钟2月12日,速度滑冰男子500米颁奖仪式上,韩国选手车旼奎夺得银牌,不过在颁奖仪式上,韩国选手在领奖前用手擦了领奖台。这一举动被转播之后,引发全球观众的中国女篮真的狠!三场大胜不输女足,男篮能学会吗?相信看过比赛的球迷都知道,我们的女篮姑娘是真的强!三场比赛均大胜对手,要知道,对手可都不弱。而我们女篮姑娘们向我们展现了新一代女篮强劲的实力。行云流水的配合,外线精准的三分,打对手