【问题标题】:How to cope with x-forwarded-headers in Spring Boot 2.2.0? (Spring Web MVC behind reverse proxy)如何应对 Spring Boot 2.2.0 中的 x-forwarded-headers? (反向代理背后的Spring Web MVC)
【发布时间】:2020-03-26 08:00:50
【问题描述】:

我的带有 Spring Web MVC 的 Spring Boot 2.2.0 应用程序在反向代理后面运行。 Spring 如何正确处理X-Forwarded-{Prefix,Host,Proto}-headers 以识别对服务器发出的实际请求?

【问题讨论】:

    标签: spring-boot spring-mvc


    【解决方案1】:

    对于 Spring Boot ForwardedHeaderFilter-Bean。从 Spring Boot 2.2.0 开始,您不必再这样做了。只需将server.forward-headers-strategy=NATIVEserver.forward-headers-strategy=FRAMEWORK 添加到您的application.properties 文件中即可。

    NATIVE 表示 servlet 容器(例如 undertow、tomcat)正在解析 x-forwarded-*-headers,这在大多数情况下都很好。如果您依赖X-Forwarded-Prefix,则必须使用FRAMEWORK,以便正确设置request.getContextPath()


    例子:

    1. 用户在浏览器中输入:https://mydomain.tld/my-microservice/actuator
    2. 微服务“my-microservice”(例如用户服务)应处理请求;它在 localhost:8080 上运行
    3. reverse-proxy 像这样转发请求:

      // Forwarded-Request from Reverse Proxy to your microservice
      GET http://localhost:8080/actuator/
      X-Forwarded-Host: mydomain.tld
      X-Forwarded-Proto: https
      X-Forwarded-Prefix: /my-microservice
      

    调试到 HttpServletRequest 将导致:

    request.getRequestURL(): "https://mydomain.tld/my-microservice/actuator/"
    request.getScheme(): "https"
    request.getContextPath(): "/my-microservice"
    new UrlPathHelper().getPathWithinApplication(request): "/actuator"
    

    【讨论】:

    • 请勿使用 server.forward-headers-strategy=FRAMEWORK 除非您知道自己在做什么,即除非您信任您的反向代理。恶意客户端可以添加他们想要的任何标头,然后... KABOOM。
    • 您也可以为 server.forward-headers-strategy=native 添加自定义代理标头。最好的选择是编写一个自定义 Zuul 过滤器,它将在 Spring Cloud 中的 PreDecorationFilter 之后发生。 PreDecorationFilter 正在查看是否设置了这些标头(在框架和本机策略中),然后“更改”主机(如果是)。我不完全确定他们为什么这样做。代理标头未标记为禁止标头,因此它们可能不被视为安全风险,而这种担忧只是妄想症
    • 嘿@phip1611,好问题。基本上,您怎么知道forwarded headers 已被代理添加并且可以信任或被恶意客户端信任?这个安全考虑也被强调了here
    • 谢谢,这让我发疯了。我在使用 Swagger UI 时遇到了重大问题,因为我们在容器的根目录上提供服务,但是通过 K8s 中的路径前缀,Swagger 将请求重定向到路由。解决方案是使用framework 级别forward-headers-strategy 并添加一个入口标签nginx.ingress.kubernetes.io/x-forwarded-prefix: "${k8s_app_path}",其中该变量是应用程序正在通过的前缀。
    • 看了又看又看,不知道怎么错过了,非常感谢!
    猜你喜欢
    • 2019-06-13
    • 2017-10-14
    • 2013-12-07
    • 2018-04-02
    • 2020-04-28
    • 2019-05-01
    • 2022-01-22
    • 1970-01-01
    • 2017-04-05
    相关资源
    最近更新 更多