记录网关zuul处理跨域/XSS问题

一,疑问

1.之前遇到跨域问题是在NG中解决的,添加跨域请求头和域名配置。那么与网关处理跨域问题关系是什么,NG处理了,为什么还需要在网关中处理

二,前置知识

zuul概念与原理

zuul 的概念和原理 - 知乎

Zuul工作原理_zuul原理_吴声子夜歌的博客-CSDN博客

梳理几个基本概念

zuul的工作原理
1.过滤器机制
zuul的核心是一系列的filters, 其作用可以类比Servlet框架的Filter,或者AOP。
zuul把Request route到 用户处理逻辑 的过程中,这些filter参与一些过滤处理,比如Authentication,Load Shedding等

2.过滤器机制过滤器类型
Zuul大部分功能都是通过过滤器来实现的。Zuul中定义了四种标准过滤器类型,这些过滤器类型对应于请求的典型生命周期。
(1) PRE:这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。
(2) ROUTING:这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用Apache HttpClient或Netfilx Ribbon请求微服务。
(3) POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。
(4) ERROR:在其他阶段发生错误时执行该过滤器

总结:通过一个个过滤器实现不同的业务逻辑,且不同过滤器类型按照顺序执行对应的业务

三,此文网关做了那几件事

1.PRE,前置需要处理的逻辑,跨域/XSS处理

2.POST,微服务处理之后记录处理时间等日志信息

具体处理逻辑

1.跨域问题重现,前端报错,如下包含了请求源Origin信息

 

 2. ZuulFilter1跨域/xss攻击代码

Component
@RefreshScope
public class TimeCostPreFilter extends ZuulFilter {
    public static final String START_TIME_KEY = "start_time";
    public static final String ZUUL_REQUEST_URL_KEY = "zuul_request_start_time";

    private static final Logger logger = LoggerFactory.getLogger(TimeCostPreFilter.class);

    @Value("${com.gateway.xss.check:true}")
    private Boolean xssCheck;

    @Value("${com.gateway.xss.url.filter:uploadFile,uploadImage}")
    private String urlFilter;

    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    /**
     * 判断是否要拦截的逻辑
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {

        long startTime = System.currentTimeMillis();
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();

        Enumeration<String> headerNames = request.getHeaderNames();
        if (headerNames != null) {
            while (headerNames.hasMoreElements()) {
                String nextElement = headerNames.nextElement();
                if (nextElement.equalsIgnoreCase("origin") && request.getHeader(nextElement) != null) {
                    String str = request.getHeader(nextElement).toLowerCase();
                    String pattern = "^(http|https)://(.*\\.skcloud\\.cn|.*\\.skcloud\\.com|.*\\.sk\\.com|localhost:?[0-9]*|api.rrx.cn|c2bt4.skcloud.com)$";

                    Pattern r = Pattern.compile(pattern);
                    Matcher m = r.matcher(str);
                    if (!m.matches()) {
                        return null;
                    }
                }
            }
        }

        StringBuffer requestUrl = request.getRequestURL();
        String url = requestUrl.toString();
        if (xssCheck) {
            if (!StringUtils.isEmpty(urlFilter)) {
                String[] urlFilterList = urlFilter.split(",");
                for (String s : urlFilterList) {
                    if (!StringUtils.isEmpty(urlFilter) && url.contains(s)) {
                        currentContext.set(ZUUL_REQUEST_URL_KEY, url);
                        currentContext.set(START_TIME_KEY, startTime);
                        return null;
                    }
                }
            }
            try {
                Map<String, String[]> map = request.getParameterMap();
                if (!(Objects.isNull(map) || map.isEmpty())) {
                    for (Map.Entry<String, String[]> entry : map.entrySet()) {
                        String[] value = entry.getValue();
                        if (extracted(currentContext, value[0])) {
                            return null;
                        }
                    }
                }
                InputStream in = request.getInputStream();
                String body = StreamUtils.copyToString(in, StandardCharsets.UTF_8);
                if (!StringUtils.isEmpty(body)) {
                    if (extracted(currentContext, body)) {
                        return null;
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        currentContext.set(ZUUL_REQUEST_URL_KEY, url);
        currentContext.set(START_TIME_KEY, startTime);
        return null;
    }

    private static boolean extracted(RequestContext currentContext, String body) {
        boolean b = checkXss(body);
        if (b) {
            currentContext.setSendZuulResponse(false);
            currentContext.setResponseBody("非法请求");
            currentContext.setResponseStatusCode(HttpStatus.BAD_REQUEST.value());
            return true;
        }
        return false;
    }

    public static boolean checkXss(String str) {
        if (StringUtils.isEmpty(str)) {
            return false;
        }
        boolean contains = str.contains("<");
        boolean contains1 = str.contains(">");
        boolean onclick = str.contains("onclick");
        return contains || contains1 || onclick;
    }

3. ZuulFilter2,日志记录

@Component
@RefreshScope
public class TimeCostPostFilter extends ZuulFilter {
    private static final String START_TIME_KE = "start_time";
    public static final String ZUUL_REQUEST_URL_KEY = "zuul_request_start_time";

    private static final Logger logger = LoggerFactory.getLogger(TimeCostPostFilter.class);

    @Autowired
    private GateWayRequestTimeClient gateWayRequestTimeClient;

    @Override
    public String filterType() {
        return FilterConstants.POST_TYPE;
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {
        RequestContext currentContext = RequestContext.getCurrentContext();
        String requestUrl = (String) currentContext.get(ZUUL_REQUEST_URL_KEY);
        long startTime = (long) currentContext.get(START_TIME_KE);
        long endTime = System.currentTimeMillis();
        long resultTime = endTime - startTime;
        int responseStatusCode = currentContext.getResponseStatusCode();
        gateWayRequestTimeClient.insertLog(startTime, endTime, resultTime, requestUrl, responseStatusCode);
        return null;
    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/11805.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

全球首个完全开源的指令跟随大模型;T5到GPT-4最全盘点

1. Dolly 2.0&#xff1a;世界上第一个完全开源的指令跟随LLM 两周前&#xff0c;Databricks发布了类ChatGPT的大型语言模型 (LLM)Dolly&#xff0c;其训练成本不到 30 美元。今天&#xff0c;他们发布了 Dolly 2.0&#xff0c;这是业内第一个开源的指令跟随LLM&#xff0c;并根…

gdb 跟踪调式core

自己编译的问题出现段错误: 编译:使用gdb调试core文件来查找程序中出现段错误的位置时,要注意的是可执行程序在编译的时候需要加上-g编译命令选项。 gdb调试core文件的步骤 gdb调试core文件的步骤常见的有如下几种,推荐第一种。 具体步骤一: (1)启动gdb,进入core文…

Midjourney详细注册和使用教程

来源&#xff1a;Midjoureny详细注册使用教程【探索ChatGPT】 Midjourney&#xff0c;用户只需要输入一段图片的文字描述&#xff0c;即可生成精美的绘画&#xff0c;相信了解Midjourey的小伙伴已经对它强大之处而赞叹&#xff01; 下面是用通俗易懂的步骤教会大家如何注册和…

企业网站架构部署与优化

系列文章目录 文章目录系列文章目录一、LAMP概述与简介1.LAMP2.各组件的主要作用如下&#xff1a;二、1.编译安装Apache http服务2.编译安装 Mysql 服务3.编译安装 PHP 解析环境总结一、LAMP概述与简介 1.LAMP LAMP架构是目前成熟的企业网站应用模式之一&#xff0c;指的是协…

Linux内核之网络协议栈以及套接字sk_buff分析

网络协议栈以及套接字sk_buff分析一、Linux 内核网络协议栈构架二、网络协议栈常见的数据结构2.1、TCP/IP 参考模型及 ISO/OSI 参考模型2.2、套接字 sk_buff 分析2.3、套接字缓冲区管理数据2.4、Linux 内核提供套接字缓冲区标准 API 函数2.5、使用一个表头来实现套接字缓冲区的…

Scala - 时间工具类 LocalDateTime 常用方法整理

目录 一.引言 二.LocalDateTime 获取与格式化 1.获取当前时间 LocalDateTime 2.根据时间戳获取 LocalDateTime 3.指定时间获取 LocalDataTime 4.LocalDataTime 格式化 三.LocalDateTime 读取时间细节 1.获取年-Year 2.获取月-Month 3.获取日-Day 4.获取时-Hour 5.获…

一文读懂域名注册

本文深入浅出讲解域名的注册、建站和管理&#xff0c;通过文章可以了解以下问题&#xff1a; 域名注册及建站流程&#xff1b;域名注册的技术原理&#xff1b;域名管理&#xff08;修改 DNS 服务器、转入转出、自定义 DNSHost、whois 信息&#xff09;。 众所周知&#xff0c;…

轨迹相似度整理

1 基于点之间的距离 1.1 欧几里得距离 优点&#xff1a;线性计算时间缺点&#xff1a;轨迹长度必须一样 1.2 DTW DTW 笔记&#xff1a; Dynamic Time Warping 动态时间规整 &#xff08;&DTW的python实现&#xff09; 【DDTW&#xff0c;WDTW】_UQI-LIUWJ的博客-CSDN博客 …

限流算法(计数器、滑动时间窗口、漏斗、令牌)原理以及代码实现

文章目录前言1、计数器&#xff08;固定时间窗口&#xff09;算法原理代码实现存在的问题2、滑动时间窗口算法原理代码实现存在的问题3、漏桶算法原理代码实现存在的问题4、令牌桶算法原理代码实现最后本文会对这4个限流算法进行详细说明&#xff0c;并输出实现限流算法的代码示…

【Redis笔记03】Redis运行环境之Cluster集群模式

这篇文章&#xff0c;主要介绍Redis运行环境之Cluster集群模式。 目录 一、Cluster集群模式 1.1、集群模式原理 &#xff08;1&#xff09;普通集群 &#xff08;2&#xff09;什么是分片&#xff1f;&#xff1f;&#xff1f; &#xff08;3&#xff09;如何分片存储&…

【操作系统复习】第4章 进程同步

进程同步的概念 主要任务 ➢ 使并发执行的诸进程之间能有效地共享资源和相互合作&#xff0c;从而使程序的执行具有可再现性。 进程间的制约关系 ➢ 间接相互制约关系(互斥关系) • 进程互斥使用临界资源 ➢ 直接相互制约关系&#xff08;同步关系&#xff09; •…

在线绘制思维导图

思维导图是一种可视化的思维工具&#xff0c;它可以将放射性思考具体化为可视的图像和图表。 思维导图利用图文并重的技巧&#xff0c;把各级主题的关系用相互隶属与相关的层级图表现出来&#xff0c;把主题关键词与图像、颜色等建立记忆链接。 它运用图像和颜色等多种元素&…

真题详解(Flynn分类)-软件设计(四十六)

真题详解&#xff08;计算机总线&#xff09;-软件设计&#xff08;四十五)https://blog.csdn.net/ke1ying/article/details/130046829 Flynn分类将计算机分为四类。 单指令流单数据流机器&#xff08;SISD&#xff09;&#xff1a;早期的机器&#xff0c;在某个时钟周期&…

某程序员哀叹:月薪四五万,却每天极度焦虑痛苦,已有生理性不适,又不敢裸辞,怎么办?...

高薪能买来快乐吗&#xff1f;来看看这位程序员的哀叹&#xff1a;实在是扛不住了&#xff0c;每天都在极度焦虑和痛苦中度过&#xff0c;早上起来要挣扎着做心理建设去上班&#xff0c;已经产生生理性的头晕恶心食欲不振。有工作本身的原因&#xff0c;更多是自己心态的问题&a…

商务接待广州考斯特商务租车详解!

进入四月份以来&#xff0c;全国各个地区都有很多商务活动举办&#xff0c;广州也不例外&#xff0c;广州很多地区都有商务活动的需求。因此不少主办方都需要商务租车来接待客户&#xff0c;而丰田考斯特是市面上常见的一款高端中巴车&#xff0c;主要是因为考斯特的可靠性、安…

CentOs的环境和配置

centos如果我们想要登录怎么办&#xff1f; 我们可以使用Xshell的远程登录 就像这样 这个就是Xshell远程登录&#xff0c;我们可以ssh root你的主机ip 然后输入密码就可以登录 就像这样 然后输入你的密码 就登录上来了&#xff0c;然后就可以进行你的操作 但是我们还可以直…

Flink 优化 (一) --------- 资源配置调优

目录一、内存设置1. TaskManager 内存模型2. 生产资源配置示例二、合理利用 cpu 资源1. 使用 DefaultResourceCalculator 策略2. 使用 DominantResourceCalculator 策略3 使用 DominantResourceCalculator 策略并指定容器 vcore 数三、并行度设置1. 全局并行度计算2. Source 端…

谷歌云服务器centos9的docker部署chat-web,实现自己的ChatGPT

谷歌云服务器centos9的docker部署chat-web&#xff0c;实现自己的ChatGPT 前提条件&#xff1a;准备一个境外服务器和chatgpt的key。&#xff08;网上教程很多&#xff09; 1.更新yum yum update2.下载docker-ce的repo curl https://download.docker.com/linux/centos/dock…

【iOS开发-响应者链Responder Chain】

文章目录0.0 前言1 响应者链&#xff08;Responder Chain1.1 响应者1.2 响应链事件1.3 响应者对象1.3.1 常见的响应者对象1.3.3 UIResponder1.3 UITouch1.3.1 UITouch的属性1.3.2 UITouch的方法1.4 UIEvent1.4.2 获取touch1.5 完整的响应者链1.5.1寻找响应者的hitTest方法1.5.2…

excel在文本的固定位置插入字符、进行日期和时间的合并

1.excel在文本的固定位置插入字符 如上图&#xff0c;现在想要将其转化为日期格式&#xff08;比如2017/1/1&#xff09;&#xff0c;但是当设置单元格格式为日期时却显示出很多&#xff03;。我们可以通过在20170101中添加两个斜杠“/”来将其转化为2017/1/1。可以用replace函…