Skip to content

HttpHeadersFilters

HttpHeadersFilters 会在将请求发送到下游之前应用(例如在 NettyRoutingFilter 中)。

1. Forwarded Headers 过滤器

Forwarded Headers 过滤器创建一个 Forwarded 头部发送给下游服务。它会将当前请求的 Host 头部、协议(Scheme)和端口添加到任何现有的 Forwarded 头部中。

要激活此过滤器,请将 spring.cloud.gateway.server.webflux.trusted-proxies 属性设置为一个 Java 正则表达式。此正则表达式定义了当它们出现在 Forwarded 头部时被认为是受信任的代理服务器。

可以通过将以下属性设置为 true(默认为 false)来启用 Forwarded 头部的 by 部分:

  • spring.cloud.gateway.server.webflux.forwarded.by.enabled=true

2. RemoveHopByHop Headers 过滤器

RemoveHopByHop Headers 过滤器从转发的请求中移除头部。默认移除的头部列表来自 IETF 规范

默认移除的头部包括:

  • Connection
  • Keep-Alive
  • Proxy-Authenticate
  • Proxy-Authorization
  • TE
  • Trailer
  • Transfer-Encoding
  • Upgrade

要更改此设置,请将 spring.cloud.gateway.server.webflux.filter.remove-hop-by-hop.headers 属性设置为要移除的头部名称列表。

3. XForwarded Headers 过滤器

XForwarded Headers 过滤器创建各种 X-Forwarded-* 头部发送给下游服务。它使用当前请求的 Host 头部、协议、端口和路径来创建各种头部。

要激活此过滤器,请将 spring.cloud.gateway.server.webflux.trusted-proxies 属性设置为一个 Java 正则表达式。此正则表达式定义了当它们出现在 X-Forwarded-* 头部时被认为是受信任的代理服务器。

可以通过以下布尔属性控制单个头部的创建(默认为 true):

  • spring.cloud.gateway.server.webflux.x-forwarded.for-enabled
  • spring.cloud.gateway.server.webflux.x-forwarded.host-enabled
  • spring.cloud.gateway.server.webflux.x-forwarded.port-enabled
  • spring.cloud.gateway.server.webflux.x-forwarded.proto-enabled
  • spring.cloud.gateway.server.webflux.x-forwarded.prefix-enabled

可以通过以下布尔属性控制是否追加多个头部(默认为 true):

  • spring.cloud.gateway.server.webflux.x-forwarded.for-append
  • spring.cloud.gateway.server.webflux.x-forwarded.host-append
  • spring.cloud.gateway.server.webflux.x-forwarded.port-append
  • spring.cloud.gateway.server.webflux.x-forwarded.proto-append
  • spring.cloud.gateway.server.webflux.x-forwarded.prefix-append

补充教学 —— 什么是 Hop-by-Hop 和 X-Forwarded?

1. Hop-by-Hop (逐跳) vs End-to-End (端到端)

HTTP 头部主要分为两类:

  • End-to-End (端到端):这类头部会一直传递给最终的接收者(例如 Content-Type, Authorization)。
  • Hop-by-Hop (逐跳):这类头部只对当前连接有效,不应该被转发给下一个节点。
    • 例如 Connection: close 是告诉网关“我和你说完话就挂电话”,网关不应该把这句话转告给下游服务,因为网关和下游服务之间可能用的是连接池(长连接)。
    • 所以,网关必须自动移除这些头部,否则会破坏通信协议。

2. X-Forwarded- vs Forwarded*

当请求经过网关(反向代理)时,下游服务接收到的 IP 通常是网关的 IP,而不是用户的真实 IP。为了解决这个问题:

  • X-Forwarded-For (传统标准)

    • 这是一个事实标准(De facto standard),用来记录“原始 IP”和“经过的代理 IP”。
    • 格式:X-Forwarded-For: client-ip, proxy1, proxy2
    • 配套的还有 X-Forwarded-Host (原始域名), X-Forwarded-Proto (原始协议 https/http)。
  • Forwarded (RFC 7239 标准)

    • 这是 IETF 推出的正式标准,试图统一乱七八糟的 X-Forwarded-*。
    • 格式:Forwarded: for=client-ip;host=original-host;proto=https

最佳实践: 大多数现代框架(包括 Spring Boot)都支持这两种格式,但 X-Forwarded-* 依然使用最广泛。配置 trusted-proxies 非常重要,否则恶意用户可以伪造这些头部来欺骗你的应用程序。

Based on Spring Framework.