spring gateway 接口返回值脱敏 -凯发k8国际

`
hbxflihua
  • 浏览: 654387 次
  • 性别:
  • 来自: 杭州
博主相关
  • 博客
  • 微博
  • 相册
  • 收藏
  • 社区版块
    • ( 0)
    • ( 0)
    • ( 1)
    存档分类
    最新评论

    spring gateway 接口返回值脱敏

    package com.huatech.gateway.filter;
    import cn.hutool.http.contenttype;
    import cn.hutool.http.header;
    import cn.hutool.json.jsonutil;
    import com.alibaba.fastjson.jsonarray;
    import com.alibaba.fastjson.jsonobject;
    import com.alibaba.fastjson.serializer.serializerfeature;
    import com.google.common.base.charsets;
    import com. huatech.gateway.utils.requestutils;
    import lombok.extern.slf4j.slf4j;
    import org.apache.commons.lang3.stringutils;
    import org.reactivestreams.publisher;
    import org.springframework.beans.factory.annotation.value;
    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.defaultdatabufferfactory;
    import org.springframework.http.httpmethod;
    import org.springframework.http.server.reactive.serverhttprequest;
    import org.springframework.http.server.reactive.serverhttpresponse;
    import org.springframework.http.server.reactive.serverhttpresponsedecorator;
    import org.springframework.stereotype.component;
    import org.springframework.util.antpathmatcher;
    import org.springframework.web.server.serverwebexchange;
    import org.springframework.web.server.webfilter;
    import org.springframework.web.server.webfilterchain;
    import reactor.core.publisher.flux;
    import reactor.core.publisher.mono;
    import java.util.iterator;
    import java.util.objects;
    /**
     * @author lihua_java@163.com
     *
     *         

    * 返回内容脱敏过滤器,将指定的字段脱敏 *

    */ @component @slf4j public class responsedesensitizefilter implements webfilter, ordered { @value("${gateway.desensitize.switch:false}") private boolean desensitizeswitch; @value("${gateway.desensitize.ignoreurls:}") private string[] ignoreurls; @value("${gateway.desensitize.fields:}") private string[] fields; private static final char desensitize_char = '*'; /** * 返回值处理 * * @param exchange * @param chain * @return */ @override public mono filter(serverwebexchange exchange, webfilterchain chain) { serverhttprequest originalrequest = exchange.getrequest(); log.debug("path : {}", originalrequest.geturi().getpath()); if(!desensitizeswitch){ return chain.filter(exchange); } if(fields == null || fields.length == 0){ return chain.filter(exchange); } if (originalrequest.getmethod() != httpmethod.post) { return chain.filter(exchange); } if(requestutils.isxhr(originalrequest) || requestutils.isminiprogram(originalrequest)){ log.debug("x-requested-with : {}", originalrequest.getheaders().getfirst(requestutils.header_key_x_request_with)); return chain.filter(exchange); } string path = originalrequest.geturi().getpath(); if(ignoreurlsmatch(path)){ log.debug("ignoreuri : {}", path); return chain.filter(exchange); } serverhttpresponse originalresponse = exchange.getresponse(); databufferfactory bufferfactory = originalresponse.bufferfactory(); serverhttpresponsedecorator decoratedresponse = new serverhttpresponsedecorator(originalresponse) { @override public mono writewith(publisher body) { if (body instanceof flux) { if (contenttype.json.tostring() .equals(originalresponse.getheaders().getfirst(header.content_type.tostring()))) { flux fluxbody = (flux)body; return super.writewith(fluxbody.buffer().map(databuffers -> { databufferfactory databufferfactory = new defaultdatabufferfactory(); databuffer join = databufferfactory.join(databuffers); byte[] content = new byte[join.readablebytecount()]; join.read(content); // 释放掉内存 databufferutils.release(join); string responsestring = new string(content, charsets.utf_8); if (stringutils.isnotblank(responsestring)) { jsonobject respjson = jsonobject.parseobject(responsestring); string data = respjson.getstring("data"); if(jsonutil.isjsonarray(data)){// 返回集合 jsonarray items = jsonobject.parsearray(data); desensitizejsonarray(items); respjson.put("data", items); }else if(jsonutil.isjsonobj(data)){// 返回单个对象 jsonobject item = jsonobject.parseobject(data); if(item.containskey("records")){// 分页 jsonarray items = item.getjsonarray("records"); desensitizejsonarray(items); }else{ desensitizejson(item); } respjson.put("data", item); } responsestring = jsonobject.tojsonstring(respjson, serializerfeature.mapsortfield); } byte[] uppedcontent = responsestring.getbytes(charsets.utf_8); return bufferfactory.wrap(uppedcontent); })); } } return super.writewith(body); } }; // replace response with decorator return chain.filter(exchange.mutate().response(decoratedresponse).build()); } private void desensitizejsonarray(jsonarray items){ if(objects.isnull(items) || items.isempty()){ return; } iterator iterator = items.stream().iterator(); while (iterator.hasnext()){ jsonobject item = (jsonobject) iterator.next(); desensitizejson(item); } } /** * 字符串脱敏 * @param item */ private void desensitizejson(jsonobject item){ if(objects.isnull(item) || item.isempty()){ return; } //log.debug("before desensitize, item : {}", item.tojsonstring()); for(string fieldkey :fields){ object field = item.get(fieldkey); if(objects.nonnull(field) && field instanceof string){ string fieldval = field.tostring(); int len = fieldval.length(); if(len <= 1){ continue; } int start = (len == 2) ? 1 : (len / 3); int end = (len == 2) ? 1 : ((len - 1) - start); fieldval = replace(fieldval, start, end, desensitize_char); item.put(fieldkey, fieldval); } } //log.debug("after desensitize, item : {}", item.tojsonstring()); } /** * 字符串替换 * @param value * @param start * @param end * @param var * @return */ private static string replace(string value, int start, int end, char var){ if(stringutils.isblank(value)){ return value; } if(end >= value.length()){ end = value.length() - 1; } if(start > end || start >= value.length()){ return value; } stringbuilder sb = new stringbuilder(value.length()); char[] vs = value.tochararray(); for(int i = 0, j = vs.length; i < j; i ){ if(i < start || i > end){ sb.append(vs[i]); }else if(i >= start && i <= end){ sb.append(var); } } return sb.tostring(); } private antpathmatcher antpathmatcher = new antpathmatcher(); private boolean ignoreurlsmatch(string path){ for(string pattern : ignoreurls){ if(antpathmatcher.match(pattern, path)){ log.debug("path match, pattern : {}, path : {}", pattern, path); return true; } } return false; } @override public int getorder() { return 101; } }

     

     

    import org.springframework.http.server.reactive.serverhttprequest;
    /**
     * @author lihua_java@163.com
     * @version 2.2.0
     * @date 2023/10/19
     */
    public class requestutils {
        public static final string header_key_x_request_with = "x-requested-with";
        public static final string header_val_mini_program_request  = "miniprogramrequest";
        public static final string header_val_xml_http_request  = "xmlhttprequest";
        public static boolean isxhr(serverhttprequest request) {
            return header_val_xml_http_request.equalsignorecase(request.getheaders().getfirst(header_key_x_request_with));
        }
        public static boolean isminiprogram(serverhttprequest request) {
            return header_val_mini_program_request.equalsignorecase(request.getheaders().getfirst(header_key_x_request_with));
        }
    }

     

    0
    0
    分享到:
    评论

    相关推荐

      实现spring-gateway登录验证码校验,使用randomstr参数作为每次生成验证码图片的唯一标识,验证码kaptcha插件

      springboot spring aop 拦截器 注解方式实现脱敏(涉及到:pom.xml -->application.properties --->启动类-->拦截器)

      spring cloud gateway的全局异常处理 spring cloud gateway中的全局异常处理不能直接用@controlleradvice来处理,通过跟踪异常信息的抛出,找到对应的源码,自定义一些处理逻辑来符合业务的需求。 网关都是给接口做...

      spring cloud gateway 版本为 3.1.3 大家好,欢迎来到阿提说说博客 “纸上得来终觉浅,绝知此事要躬行。”(南宋)陆游 目前相关的教程虽然有很多,但总觉得被各位大佬压缩,看到的只是一部分知识,并不全面,...

      1.本项目为springcloud gateway的微服务框架,整合了springsecurity,微服务间使用redis来获取登陆的用户信息。 2.由于gat

      spring官方博客发布了一篇关于spring cloud gateway的cve报告,据公告描述,当启用和暴露 gateway actuator 端点时,使用 spring cloud gateway 的应用程序可受到代码注入攻击。攻击者可以发送特制的恶意请求,从而...

      springcloud gateway 全局滤器 统一签名判定

      springgateway集成oauth2进行认证授权;还可以这么玩;sso功能的认证;自己测试正常;springgateway集成oauth2进行认证授权;还可以这么玩;sso功能的认证;自己测试正常;springgateway集成oauth2进行认证授权;还...

      赠送jar包:spring-cloud-gateway-server-3.1.1.jar; 赠送原api文档:spring-cloud-gateway-server-3.1.1-javadoc.jar; 赠送源代码:spring-cloud-gateway-server-3.1.1-sources.jar; 赠送maven依赖信息文件:...

      赠送jar包:spring-cloud-gateway-server-3.1.1.jar; 赠送原api文档:spring-cloud-gateway-server-3.1.1-javadoc.jar; 赠送源代码:spring-cloud-gateway-server-3.1.1-sources.jar; 赠送maven依赖信息文件:...

      自定义注解结合hutool对springboot接口返回数据进行脱敏 自定义注解结合hutool对springboot接口返回数据进行脱敏 自定义注解结合hutool对springboot接口返回数据进行脱敏 自定义注解结合hutool对springboot接口返回...

      websocket,springcloud

      1.本项目为springcloud gateway的微服务框架,整合了springsecurity,微服务间使用redis来获取登陆的用户信息。 2.由于gateway采用的是纯webflux方式,所以原有的spring基于传统拦截器、过滤器的方式无法正常使用...

      spring cloud gateway的负载均衡和动态路由的实现 demo_01,demo_02,demo_03 这三个服务相当于是集群的微服务 gateway这个服务是 springcloude gateway ribbon 做的负载均衡 gateway_01 这个服务 是动态路由的...

      这个项目提供了一个构建在 spring 生态系统之上的 api 网关,包括:spring 5,spring ... spring cloud gateway 旨在提供一种简单而有效的 api 路 由方式,并为其提供横切关注点,例如:安全,监控/指标和弹性。

      在接入spring-cloud-gateway时,可能有需求进行缓存json-body数据或者form-urlencoded数据的情况。这篇文章主要介绍了springcloud finchley gateway 缓存请求body和form表单的实现,感兴趣的小伙伴们可以参考一下

      赠送jar包:spring-cloud-gateway-server-3.0.4.jar; 赠送原api文档:spring-cloud-gateway-server-3.0.4-javadoc.jar; 赠送源代码:spring-cloud-gateway-server-3.0.4-sources.jar; 赠送maven依赖信息文件:...

      内容:完整集成了spring gateway, spring security, nacos, oauth2, rbac, 手机验证码登录等sso统一认证平台,全平台唯一,全平台最全,全面细致,已经帮你踩了很多坑,一看就会,可以本地运行,或者直接作为认证...

      spingcloud gateway简单实例源码,spring-cloud-gateway-sample

      普通javaweb项目调用springcloud接口(超级实用,很详细)但是要注意的事一定要对springboot和springcloud的有所了解,不然的话你也是看不懂的,大家一起努力共同学习

    global site tag (gtag.js) - google analytics
    网站地图