1. 背景

最近,需要提升系统安全性,市面上有很多款网关服务的技术方案,最终选择了Spring Cloud Gateway

2. Spring Cloud Gateway工作机制

官网配图:

客户端向Spring Cloud Gateway发出请求。如果网关处理程序映射确定一个请求匹配一个路由,它将被发送到网关Web处理程序。此处理程序通过特定于请求的过滤器链运行请求。虚线分隔过滤器的原因是,过滤器可以在发送代理请求之前和之后运行逻辑。执行所有“预”筛选逻辑。然后发出代理请求。发出代理请求后,运行“post”筛选器逻辑。

注意:在没有端口的路由中定义的uri, HTTP和HTTPS uri的默认端口值分别为80443

2.1 路由断言工厂

Spring Cloud Gateway可以匹配各种路由,而其内部就包括许多内置的路由断言工厂。所有这些断言都匹配HTTP请求的不同属性。您可以将多个路由断言工厂与逻辑和语句组合在一起使用。

2.1.1 路由后断言工厂(The After Route Predicate Factory)

路由后断言工厂可以接受一个datetime的时间参数。此断言匹配发生在指定日期时间之后的请求。配置示例如下:

spring:cloud:gateway:routes:- id: after_route   # 路由 Id,唯一uri: https://www.baidu.com    # 目标 URI, 路由到微服务的地址predicates:       # 断言(判断条件)- After=2022-01-20T17:42:47.789-07:00[America/Denver]     # 采用的是路由后断言工厂,配置时间

配置解读: 设置某个时间点,等当前时间在该条件之后就可以进行访问该路由,即访问该服务地址。

注意:

  • 如果有多个满足条件的after配置,则会路由到第一个uri。

  • 参数格式,满足ZonedDateTime格式,

2.1.2 路由前断言工厂(The Before Route Predicate Factory)

路由断言工厂接受一个参数,即datetime。这个工厂其实跟前一个介绍的工厂效果恰恰是相反,也就是断言匹配发生在指定日期时间之前的请求。配置示例如下:

spring:cloud:gateway:routes:- id: before_route   # 路由 Id,唯一uri: https://example.org      # 目标 URI, 路由到微服务的地址predicates:       # 断言(判断条件)- Before=2017-01-20T17:42:47.789-07:00[America/Denver]    # 使用路由前断言工厂,配置时间

配置解读: 设置某个时间点,等当前时间在该条件之前都可以进行访问该路由,即访问该服务地址。

2.1.3 间隔路由断言工厂(The Between Route Predicate Factory)

这个路由工厂的作用顾名思义就是设置在一个时间范围内允许访问该服务地址,配置事例如下:

spring:cloud:gateway:routes:- id: between_route   # 路由 Id,唯一uri: https://example.org      # 目标 URI, 路由到微服务的地址predicates:- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]      # 使用间隔路由断言工厂,配置时间范围

配置解读: 设置某个时间范围,等当前时间在该时间范围的条件之内都可以进行访问该路由,即访问该服务地址。

2.1.4 Cookie路由断言工厂(The Cookie Route Predicate Factory)

通过cookie和一个正则表达式作为断言条件的路由工厂,只要满足该条件就可以访问到该地址。

spring:cloud:gateway:routes:- id: between_route   # 路由 Id,唯一uri: https://example.org      # 目标 URI, 路由到微服务的地址predicates:- Cookie=chocolate, ch.p   # 使用Cookie路由断言工厂,配置cookie,正则表达式(可有可无)

配置解读:此路由将匹配具有一个名为chocolate的cookie的请求,该cookie的值匹配ch.p正则表达式。

2.1.5 请求头路由断言工厂(The Header Route Predicate Factory)

请求头路由断言工厂接受两个参数,报头名称和一个正则表达式。该断言与具有给定名称的头匹配,该名称的值与正则表达式匹配。下面的例子配置了:

spring:cloud:gateway:routes:- id: header_routeuri: https://example.orgpredicates:- Header=X-Request-Id, \d+

配置解读:如果请求有一个名为X-Request-Id的请求头,其值匹配\d+正则表达式(也就是说,它有一个或多个数字的值),则此路由匹配。

2.1.6 主机路由断言工厂(The Host Route Predicate Factory)

主机路由断言工厂接受一个参数:主机名模式列表。该模式是一个ant样式的模式,通过 " . " 作为分隔符。这个断言匹配模式匹配的是Host头。配置示例如下:

spring:cloud:gateway:routes:- id: between_route   # 路由 Id,唯一uri: https://example.org      # 目标 URI, 路由到微服务的地址predicates:- Host=**.somehost.org,**.anotherhost.org     #使用主机路由断言工厂

配置解读:

URI模板变量(例如{sub}.myhost.org)也被支持。

如果请求的Host报头值为www.somehost.org或beta.somehost.org或www.anotherhost.org,则此路由匹配。

这个谓词提取URI模板变量(例如sub,在前面的例子中定义)作为名称和值的映射,并将其与在ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE中定义的键放在ServerWebExchange.getAttributes()中。这些值可以被GatewayFilter工厂使用。

2.1.7 方法路由断言工厂 (The Method Route Predicate Factory)

方法路由断言工厂接受一个方法参数,它是一个或多个参数:要匹配的HTTP方法。配置示例如下:

spring:cloud:gateway:routes:- id: between_route   # 路由 Id,唯一uri: https://example.org      # 目标 URI, 路由到微服务的地址predicates:- Method=GET,POST    #使用方法路由断言工厂 

配置解读:如果请求方法是GET或POST,则此路由匹配。

2.1.8 路径路由断言工厂(The Path Route Predicate Factory)

路径路由断言工厂接受两个参数:一个Spring PathMatcher模式列表和一个名为matchTrailingSlash的可选标志(默认为true)。配置示例如下:

spring:cloud:gateway:routes:- id: between_route   # 路由 Id,唯一uri: https://example.org      # 目标 URI, 路由到微服务的地址predicates:- Path=/red/{segment},/blue/{segment}    #使用路径路由断言工厂

配置解读:

如果请求路径符合以上断言要求,则由该路由匹配,例如:  /red/1  或    /red/1/   或    /red/blue或     /blue/green。

如果将matchTrailingSlash设置为false,那么请求路径/red/1/将不会被匹配。

这个断言提取URI模板变量(例如在前面的例子中定义的segment)作为名称和值的映射,并将其与在ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE中定义的键放在ServerWebExchange.getAttributes()中。这些值可以被GatewayFilter工厂使用。

可以使用一个实用方法(称为get)来简化对这些变量的访问。下面的例子展示了如何使用get方法:

Map<String, String> uriVariables = ServerWebExchangeUtils.getPathPredicateVariables(exchange);String segment = uriVariables.get("segment");

2.1.9 查询路由断言工厂 (The Query Route Predicate Factory)

查询路由断言工厂接受两个参数:一个必需的参数和一个可选的regexp(它是一个Java正则表达式)。配置示例如下:

spring:cloud:gateway:routes:- id: query_routeuri: https://example.orgpredicates:- Query=green

配置解读:如果请求包含green查询参数,则上述路由匹配。

spring:cloud:gateway:routes:- id: query_routeuri: https://example.orgpredicates:- Query=red, gree.

配置解读:如果请求中包含一个red的查询参数,且该参数的值匹配gree. 正则表达式(即green,gree2都是可以的),则上述路由匹配。,所以red和greet是匹配的。

2.1.10 远程地址路由断言工厂(The RemoteAddr Route Predicate Factory)

远程地址路由断言工厂接受一个源列表(最小大小为1),它是 CIDR-notation (IPv4 or IPv6) ,例如192.168.0.1/16(其中192.168.0.1是一个IP地址,16是一个子网掩码)。配置示例如下:

spring:cloud:gateway:routes:- id: remoteaddr_routeuri: https://example.orgpredicates:- RemoteAddr=192.168.1.1/24

配置解读:如果请求的远端地址是,例如192.168.1.10,则此路由匹配。

  1. 修改远端地址解析方式

默认情况下,远程地址路由断言工厂使用来自传入请求的远程地址。如果Spring Cloud Gateway位于代理层后面,这可能与实际的客户端IP地址不匹配。

你可以通过设置一个自定义的RemoteAddressResolver来自定义远程地址解析的方式。Spring Cloud Gateway提供了一个非默认的远程地址解析器,它基于X-Forwarded-For报头,即XForwardedRemoteAddressResolver。

XForwardedRemoteAddressResolver有两个静态构造函数方法,它们采用不同的安全方法:

  • XForwardedRemoteAddressResolver::trustAll返回一个RemoteAddressResolver,它总是采用X-Forwarded-For头中发现的第一个IP地址。这种方法很容易受到欺骗,因为恶意客户端可能会为X-Forwarded-For设置初始值,解析器将接受该初始值。
  • XForwardedRemoteAddressResolver::maxTrustedIndex获取一个与Spring Cloud Gateway前面运行的可信基础设施数量相关的索引。例如,如果Spring Cloud Gateway只能通过HAProxy访问,那么应该使用值1。如果在访问Spring Cloud Gateway之前需要信任基础设施的两个跃点,那么应该使用值2。

考虑以下报头值:

X-Forwarded-For: 0.0.0.1, 0.0.0.2, 0.0.0.3

下面的maxTrustedIndex值产生以下远程地址:

下面的例子展示了如何用Java实现相同的配置:

RemoteAddressResolver resolver = XForwardedRemoteAddressResolver.maxTrustedIndex(1);....route("direct-route",r -> r.remoteAddr("10.1.1.1", "10.10.1.1/24").uri("https://downstream1")
.route("proxied-route",r -> r.remoteAddr(resolver, "10.10.1.1", "10.10.1.1/24").uri("https://downstream2")
)

2.1.11 权重路由断言工厂(The Weight Route Predicate Factory)

权重路由断言工厂接受两个参数:group和Weight(一个int类型)。权重按每组计算。配置示例如下:

spring:cloud:gateway:routes:- id: weight_highuri: https://weighthigh.orgpredicates:- Weight=group1, 8- id: weight_lowuri: https://weightlow.orgpredicates:- Weight=group1, 2

 配置解读:将把80%的流量转发到weighthigh.org, 20%的流量转发到weighlow.org

2.1.12  The XForwarded 远程地址路由断言工厂(The XForwarded Remote Addr Route Predicate Factory)

The XForwarded 远程地址路由断言工厂接受一个源列表(最小大小为1),它它是 CIDR-notation (IPv4 or IPv6) ,例如192.168.0.1/16(其中192.168.0.1是一个IP地址,16是一个子网掩码)。

这个路由断言允许基于X-Forwarded-For HTTP头对请求进行过滤。

这可以用于反向代理,如负载均衡器或web应用程序防火墙,在这些反向代理中,只有当请求来自由这些反向代理使用的可信IP地址列表时,才应该允许该请求。

配置示例如下:

spring:cloud:gateway:routes:- id: xforwarded_remoteaddr_routeuri: https://example.orgpredicates:- XForwardedRemoteAddr=192.168.1.1/24

配置解读:如果X-Forwarded-For报头包含192.168.1.10,则此路由匹配。

Spring Cloud Gateway之路由断言工厂篇相关推荐

  1. Spring Cloud Gateway 动态路由管理,一点都不吹,应该没有比这更好的管理系统了吧

      本文介绍的 Spring Cloud Gateway 动态路由.不比其他博客通篇 copy 的 Gateway 动态路由,直接上干货!!!为你们提供了一套完整的动态路由管理系统.文末附本文全套代码 ...

  2. Spring Cloud Gateway(路由)

    本篇文章主要介绍了什么是 Spring Cloud Gateway,并基于 Spring Cloud Gateway 的 Finchley.RC1 版本编写一个 Spring Cloud Gatewa ...

  3. Nacos + Spring Cloud Gateway动态路由配置

    前言 Nacos最近项目一直在使用,其简单灵活,支持更细粒度的命令空间,分组等为麻烦复杂的环境切换提供了方便:同时也很好支持动态路由的配置,只需要简单的几步即可.在国产的注册中心.配置中心中比较突出, ...

  4. Spring Cloud Gateway CORS 方案看这篇就够了

    欢迎关注方志朋的博客,回复"666"获面试宝典 在 SpringCloud 项目中,前后端分离目前很常见,在调试时,会遇到两种情况的跨域: 前端页面通过不同域名或IP访问微服务的后 ...

  5. Gateway网关-路由断言工厂

    断言工厂 我们在配置文件中写的断言规则只是字符串,这些字符串会被Predicate Factory读取并处理,转变为路由判断的条件 例如Path=/user/**是按照路径匹配,这个规则是由 org. ...

  6. Spring Cloud Gateway动态路由实现

    Gateway上线部署分析 当你的网关程序开发完成之后,需要部署到生产环境,这个时候你的程序不能是单点运行的,肯定是多节点启动(独立部署或者docker等容器部署),防止单节点故障导致整个服务不能访问 ...

  7. 微服务网关Zuul迁移到Spring Cloud Gateway

    https://juejin.im/post/5ba8daa56fb9a05cfe486ebf 背景 在之前的文章中,我们介绍过微服务网关Spring Cloud Netflix Zuul,前段时间有 ...

  8. Spring Cloud Gateway 路由转发之After(Before)路由断言工厂使用

    前言 本文旨在介绍After(Before)路由断言工厂使用,以此类推可以使用其他路由断言工厂 案例 1.概念 网关简单的说就是提供一个对外统一的API入口和出口,统管企业对外的所有API出口.一般来 ...

  9. 跟我学SpringCloud | 第十二篇:Spring Cloud Gateway初探

    SpringCloud系列教程 | 第十二篇:Spring Cloud Gateway初探 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如 ...

最新文章

  1. 火山引擎向企业客户开放上万款抖音同款特效
  2. php对长文章进行分页处理
  3. python游戏编程入门-python游戏编程入门
  4. react native windows 搭建(完整版)
  5. CTFshow php特性 web137
  6. Java的native关键字
  7. 【视频教程】利用Excel轻松爬取网页上的数据
  8. Leetcode第286场周赛
  9. 优客365导航系统美化UI版源码-带交易功能
  10. 你知道undefined与null的区别吗?
  11. 全国Python科研应用专题实操培训班
  12. python的aes的ecb加密_AES ECB PKCS5/PKCS7 加密 python实现 支持中文
  13. matlab u怎么求均方差,Matlab求方差,均值,均方差,協方差的函數
  14. 想打游戏/追剧,又放心不下学习,该怎么办?
  15. 爬虫:Python爬取煎蛋网图片
  16. 以太网 STP临时环路的产生、STP BPDU的转发过程、根桥故障案例分析。
  17. 抖音xlog算法分析
  18. 奇安信2022面试题
  19. VMware Ubuntu18.04与WIN7共享目录
  20. Host 'X.X.X.X' is blocked because of many connection errors; unblock with 'mysqladmin flush-ho

热门文章

  1. 如何给WORD文档加注释?
  2. Eclipse注释汉字开始的文字是方框问题
  3. JS调用浏览器不能全屏适应A4纸解决办法
  4. FART一键刷机脚本
  5. OpenCV 读取视频,设置起始帧、结束帧及如何获取帧率
  6. 【unity游戏开发教程】Unity+Umotion Pro+VRoid+Blender制作人物模型和动画,在unity中简单制作二次元人物动画
  7. 雷电模拟器怎么让有一些用另外一条网络_对不起了“网易”,阉割版似乎更好用...
  8. Python神经网络编程(TR) (3)
  9. 3 判断单链表的对称性
  10. android从本地相册获取图片uri三星手机适配问题