news 2026/9/9 19:21:48

Spring Boot 部署在反向代理后面时如何配置转发头(forward-headers-strategy)?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring Boot 部署在反向代理后面时如何配置转发头(forward-headers-strategy)?

Spring Boot 部署在反向代理后面时如何配置转发头(forward-headers-strategy)?

【免费下载链接】spring-bootSpring Boot helps you to create Spring-powered, production-grade applications and services with absolute minimum fuss.项目地址: https://gitcode.com/gh_mirrors/sp/spring-boot

当 Spring Boot 应用部署在反向代理、负载均衡器或云平台之后时,应用看到的请求信息(主机名、端口、协议等)可能在中转过程中发生变化——应用可能实际运行在10.10.10.10:8080,但 HTTP 客户端只应该看到example.org。Spring Boot 用server.forward-headers-strategy配置项告诉应用如何读取代理附加在请求上的转发头(forwarded headers),并让应用在创建链接、通过 HTTP 302 响应、JSON 文档或 HTML 页面把链接发送给客户端时自动使用这些信息。本文按“确认代理发送哪组头 → 选择策略 → 按内嵌服务器微调 → 注意信任边界”的顺序给出完整配置路径。

先确认代理发送的是哪一组转发头

中间代理可以用两组 HTTP 头来携带原始请求信息:

  1. 通用的"X-Forwarded-*"头,如"X-Forwarded-Host""X-Forwarded-Port""X-Forwarded-Proto""X-Forwarded-For"
  2. "Forwarded"头,由 RFC7239 "Forwarded Headers" 定义。

配置策略的第一步是查清你的代理、负载均衡器或云平台实际发送哪一组。文档指出 RFC7239 虽是标准但业界采用率很低,实践中你大概率需要的是"X-Forwarded-*"。只有确认了头格式,后面的策略选择才有依据。

选择策略:NATIVE 还是 FRAMEWORK

server.forward-headers-strategy有三个取值(见 ServerProperties 中的ForwardHeadersStrategy枚举):

  • NATIVE:使用内嵌容器自身对转发头的支持;
  • FRAMEWORK:使用 Spring Framework 提供的支持;
  • NONE:忽略X-Forwarded-*头。

关于默认值:当应用运行在一个受支持的云平台上时,server.forward-headers-strategy默认为NATIVE;其他所有情况下默认为NONE。Spring Boot 通过环境变量推断云平台(例如 Kubernetes 环境检查*_SERVICE_HOST*_SERVICE_PORT变量,AWS ECS 检查AWS_EXECUTION_ENV),并可用spring.main.cloud-platform属性覆盖这一检测。

主路径:NATIVE

如果所选的 web server 支持你需要的头格式,文档给出的建议是把server.forward-headers-strategy设为NATIVE。各服务器的支持情况:

Server支持的转发头
Tomcat"X-Forwarded-*"
Jetty"X-Forwarded-*""Forwarded"
Reactor Netty"X-Forwarded-*""Forwarded"

配置示例:

server: forward-headers-strategy: NATIVE

备选:FRAMEWORK

如果容器的原生支持不够,可以使用 Spring Framework 提供的转发头组件:Spring MVC 应用对应ForwardedHeaderFilter,WebFlux 应用对应ForwardedHeaderTransformer。配置方式为把server.forward-headers-strategy设为FRAMEWORK,并用对应栈的属性选择头格式:

  • Spring MVC:spring.mvc.forwarded-headers.header-format
  • WebFlux:spring.webflux.forwarded-headers.header-format

header-format的取值对应两种头格式:STANDARD使用 RFC 7239 定义的Forwarded头,X_FORWARDED使用非标准的X-Forwarded-*头(见 WebFluxProperties 中的HeaderFormat枚举)。

server: forward-headers-strategy: FRAMEWORK spring: webflux: forwarded-headers: header-format: STANDARD

按内嵌服务器做针对性微调(可选分支)

只有当 NATIVE 的默认行为与你的代理配置不完全匹配时,才需要进入这一节。

Tomcat

使用 Tomcat 时,可以额外配置用于携带转发信息的头名称:

server: tomcat: remoteip: remote-ip-header: "x-your-remote-ip-header" protocol-header: "x-your-protocol-header"

Tomcat 还用一个正则表达式匹配应当被信任的内部代理。可以往application.properties中加一条来自server.tomcat.remoteip.internal-proxies的自定义项(默认值见附录属性索引):

server: tomcat: remoteip: internal-proxies: "192\\.168\\.\\d{1,3}\\.\\d{1,3}"

注意:把internal-proxies设为空可以信任所有代理,但文档明确提示不要在生产环境这样做。

一条与跳转直接相关的提示:如果你使用 Tomcat、在代理端终结 SSL,并且已经把server.tomcat.servlet.use-relative-redirects设为false,那么还应把server.tomcat.servlet.redirect-context-root也设为false,这样才能让X-Forwarded-Proto头在执行任何重定向前被正确采用;而当使用相对重定向(Tomcat 的默认行为)时,context root 重定向本身不携带 scheme,也就没有可供该头纠正的内容。

如果需要完全接管 TomcatRemoteIpValve的配置,可以把自动配置关掉(设server.forward-headers-strategy=NONE),再通过WebServerFactoryCustomizerbean 添加一个新的 valve 实例。

Jetty

Jetty 默认使用"X-Forwarded-*"格式,可以切换为标准 RFC 变体:

server: jetty: forwarded-headers: header-format: "standard"

需要更多选项时,把server.forward-headers-strategy设为NONE,直接使用 Jetty 的ForwardedRequestCustomizer修改 HTTP 配置。

Reactor Netty

Reactor Netty 同样默认使用"X-Forwarded-*"格式,可切换为标准 RFC 变体:

server: netty: forwarded-headers: header-format: "standard"

需要更多选项时,把server.forward-headers-strategy设为NONE,直接使用reactor.netty.http.server.HttpServer的 forwarded header 支持。

信任边界:只在可信代理后面启用

文档在云部署的安全注意事项中给出的原则是:支持转发头应当仅在应用从受信任的 HTTP 代理接收流量、并且只能从受信任网络直接访问时才启用。在云平台运行时,转发头会被自动启用,这基于一个假设:平台会保证单个应用实例只能从受信任网络直接访问。如果你的特定平台不满足这个条件,把server.forward-headers-strategy设为none

server: forward-headers-strategy: none

如何验证配置生效

文档描述该功能生效后的行为是:应用自动使用转发头携带的信息来创建链接,并在 HTTP 302 响应、JSON 文档或 HTML 页面中把这些链接发送给客户端。因此验证方式是:通过代理的外部地址访问应用,检查返回给客户端的链接(包括重定向目标)使用的是外部主机名和协议(例如https://example.org),而不是应用内部实际监听的地址和端口。若你的代理终结了 SSL,重点检查 302 重定向目标是否采用了X-Forwarded-Proto提供的协议;对于 Tomcat,这依赖前面提到的redirect-context-root相关设置。

本文内容整理自仓库内的 Embedded Web Servers(how-to) 和 Deploying to the Cloud(how-to)。

【免费下载链接】spring-bootSpring Boot helps you to create Spring-powered, production-grade applications and services with absolute minimum fuss.项目地址: https://gitcode.com/gh_mirrors/sp/spring-boot

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/9 19:19:44

苏州Android工程师岗位深度拆解:从应用层到系统层面试准备

周六晚上刷到一条苏州虹保世纪科技的 Android 开发工程师岗位推送,JD 写得挺实诚,技术栈列得算清楚,待遇区间也标了范围。我把这家公司近两三年放出来的 Android 相关职位、面试反馈和内部工具链信息翻了个遍,也对照了苏州本地同类…

作者头像 李华
网站建设 2026/9/9 19:19:09

共享储能与多类型负荷需求响应的园区经济运行优化研究

做园区级能量管理项目的时候,我一直有一个很深的感受:很多园区把储能、负荷、光伏当成三个割裂的模块来调度,储能利用率低、负荷侧白白浪费了调节空间,最后算经济账非常难看。这个“含共享储能的园区多类型负荷需求响应经济运行研…

作者头像 李华
网站建设 2026/9/9 19:17:42

AI编码中spec与plan:从模糊需求到可验收交付的关键

写代码这行当干了十几年,最近半年我几乎天天泡在AI coding工具里,越用越觉得有个概念被大家混得厉害:spec和plan。不少人跟我抱怨,说让AI先做plan再写代码,结果写完还是一堆bug,甚至方向直接跑偏。我问他&a…

作者头像 李华
网站建设 2026/9/9 19:17:36

GPT Academic 如何用动态代码解释器批量处理图片、CSV 与文本文件?

GPT Academic 如何用动态代码解释器批量处理图片、CSV 与文本文件? 【免费下载链接】gpt_academic 为GPT/GLM等LLM大语言模型提供实用化交互接口,特别优化论文阅读/润色/写作体验,模块化设计,支持自定义快捷按钮&函数插件&…

作者头像 李华