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

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请求
  服务器日志

什么时间喝茶最养生?什么时间不适合喝茶?欢迎关注懂茶帝不同的场合不同的体质不同的年纪要喝对茶才更健康,否则可能会让身体不适,甚至雪上加霜,下面我们就一起来了解一下,什么时间该喝什么茶。早上适宜喝红茶妙招推荐人在睡了一夜之中国驾照考试的难度是在增加吗?考驾照尊加难度有用吗,反而交通事故越来越多,是什么原因?最大凶手就是车保害死人。发生事故有什么大不了的,不管是谁违章,我只听到一句话。我是投的全保无所谓,有保险公司呢。轻松的一句话如果马超与赵云联手,击败吕布有难度吗?马超赵云吕布都是三国时期的人物并且他们都是武艺超群之人。同时在三国演义之中马超和赵云都人刘备账下的猛将,皆位列五虎上将之中,而吕布则有人中吕布的称号,也是当时公认的猛将。那如果马超普通人适不适合使用5G手机?5G手机广泛使用于哪些人?感谢邀请普通人适不适合使用5G手机?5G手机广泛使用于哪些人?我认为现在普通人适合使用5G手机。因为我们现在从手机市场可以看到基本上都是5G手机,而且我们可以看到现在人们购买的也都等到年底比特币暴跌的时候,会不会踊跃出更多人坚定的相信比特币是骗局?一直说是骗局的肯定是没有买币的人,如果是币圈的就不会认定是骗局。因为确实有人在币圈这种新兴的投机市场中赚到钱,而且是超过传统市场的收益率。既然赚到钱那肯定是不会把它当骗局的,只有没有什么专业的难度是被严重低估的?我觉得是数学。对学霸学神来说,数学是很简单的,至少在被打击之前是这么认为的。我身边有两个例子A同学从小就是别人家的孩子,数学竞赛保送北大,自信满满地选了数学系,大二时主动要求转专业给老人用什么牌子的智能机比较好?给家中的老人使用智能手机应该如何选择品牌,其实对于老人所使用的智能手机来说,主要需要明确其特殊的用户需求就可以了,对于这样的需求来说,我们首先要明确,对于老年人来说,哪些功能或者特我家的邻居在自己的地里土葬老人,离我家只有十米远,我该怎么办?看到好多人都在说,邻居是在自己地里土葬老人,你无权干涉,也不用问怎么办。理由是那是人家自己的地,你奈何?又没葬在你家土地里。我对这种说法,是有看法的。第一,请大家仔细看清楚,离我家拳皇97挑衅动作既然没用,为什么当初要有这个设定?拳皇系列的每一个设定,其实都是有道理的。挑衅这个设定在SNK的系列游戏中由来已久,几乎所有的格斗游戏中都有类似的设定。而这个挑衅并非单纯是嘲讽玩家,还有其他比较有意思的隐藏属性。这每月养老金一到账,老人们马上去银行提出来,为什么?小区张大爷每月退休金275O元,退休快十年了,退休时才八百多元,连续这么多年涨,才有今天这些退休金。他退休前是社办企业的一名工人,基础缴费低,年限交的短,所以退休金就少。但现在这些2018秋季女裤流行趋势是什么?感谢邀请。大家好,我是哆咪,欢迎关注哆咪衣橱,学穿衣搭配做时尚女王!要说2018秋季女裤的流行趋势,那么必定是万能百搭的烟管裤了,烟管裤版型藏肉显瘦显腿直不挑人,都市丽人休闲时髦都
武汉每晚最低温都在零度常吃5种食物帮你健康过冬!武汉市气象台预计,未来三天武汉晴天到多云,早晚温差较大,空气质量轻度污染,老人和孩子适当减少外出,注意保暖。今天白天晴天最高气温12,最低气温1湿度5090,风偏北风3级明天晴天到男人40岁以后,想要提升肾动力,5种食物可多吃常言道男人四十一枝花,女人四十如桑麻,在当今社会,这句话似乎要改过来,现如今,女性哪怕到了40岁,依然打扮的光鲜亮丽,反观男人则如桑麻般顶着啤酒肚,脸上胡子拉碴,早已失去了曾经的光白癜风患者吃什么补锌?这几种食物可以推荐众所周知,缺乏微量元素是白癜风的诱发因素之一。在日常饮食辅助白癜风治疗时,常常被提到的是铜元素,但实际上锌元素也是可以辅助合成黑色素的。锌元素可以参与体内多种酶的合成,从而对人体内胃病患者冬季如何养胃?这份养胃攻略请查收红网时刻新闻12月13日讯(通讯员舒丽)胃病是一种常见病,生活中不少人会因为不注重养胃护胃而患上了或大或小的胃病,而到了冬天,寒冷的环境会让胃部受到的刺激更大,导致很多人的胃病有复2022年设计师电脑配置购买设计师电脑配置需要遵循3大原则第一原则不要盲目追求高配置,适合自己才最好电脑属于电子产品,更新周期快,不要盲目追求发烧配置,再发烧的配置,也会过时,电脑和车一样,二手不值钱。最2023款AIONY续航610KM智能配置,值得入手吗今天我们要体验的车型是广汽埃安新能源旗下的AIONY(图片配置询价),这款车定位于纯电动紧凑型SUV,2023款车型上市不久,相比现款车型续航里程做了升级,补贴后的售价区间为13。投影机有没有蓝光?上课用的投影仪有蓝光吗?了解一下投影机有没有蓝光?投影机有蓝光,投影机作为显示设备,内部光机投出去会有蓝光。尤其是现在市面上的激光投影机,大部分都是用蓝光激发荧光粉来实现显色的。不过不用担心,投影机的画面是通过投RoyalTSX从入门到高效使用RoyalTSX是一款macOS下可用的远程连接软件,类似于Windows系统的XShell。免费版最多支持10个连接,对于个人开发而言,已经足够了引言在Windows系统下连接远LG将推43SQ700S显示器42。5英寸4K分辨率,内置电视系统IT之家12月14日消息,LG即将推出一款43SQ700S显示器,42。5英寸4K分辨率规格,内置电视系统。据介绍,这款显示器将搭载42。5英寸的IPS屏幕,4K分辨率,60Hz刷研究发现小行星撞击地球时恐龙种群正值鼎盛时期具有里程碑意义的研究显示,在6600万年前一颗致命的小行星撞击地球导致它们大规模灭绝之前,恐龙一直统治着世界。该研究结果于12月7日发表在科学进展杂志上,提供了迄今为止最有力的证据国际最新研究首次录到火星尘卷风之声风宽25米高118米此图显示尘卷风相对于毅力号火星车的大小(图源NMurdoch,法国国立高等航空航天学院)。施普林格自然供图中新网北京12月14日电(记者孙自法)火星上刮尘卷风吗?风有多大?风声如何