Forward Headers 在 Spring Boot + Kubernetes 中不起作用
回答问题
背景
我最近将我的 Spring 应用程序迁移到 Spring Boot(带有嵌入式 Tomcat),我目前正在将它迁移到 Kubernetes。作为迁移到 Kubernetes 的一部分,我将 Apache 配置分离到它自己的服务中,并在 Kubernetes 中部署以充当我的 Spring Boot 应用程序的代理。
我当前的设置是带有 LoadBalancer 服务的 Apache,它接受来自世界各地的请求。这会接收这些请求并将它们转发到我的 Spring Boot 应用程序,该应用程序具有 ClusterIP 服务。
另外需要注意的是:我的 Apache 将所有 http 重定向到 https。
问题
每当我的 Spring Boot 应用程序向客户端返回重定向时,响应中的位置标头是 http 而不是 https(只有通过 https 发出的请求才会通过 Apache 代理到达我的应用程序)。
例子:
未登录用户前往:
https://example.com/admin
如果未通过身份验证,则管理页面会将用户重定向到登录页面。这应该是一个重定向到:
https://example.com/login
但是,我的应用程序将用户重定向到:
http://example.com/login
然后用户被 Apache 再次重定向到:
https://example.com/login
我试过的
我检查了我的日志,以确保我的应用收到的请求包含X-Forwarded-Proto: https标头,据我了解,这应该使重定向响应 https 中的位置标头。
正如几篇 Stack Overflow 帖子中提到的,我尝试将server.use-forward-headers=true添加到我的application.properties文件中,但这没有任何作用。我也尝试用它添加server.tomcat.protocol-header=X-Forwarded-Proto,但这也没有做任何事情(从我读到的,无论如何都是默认值)。
其他说明
-
我的集群的
networkCIDR包含在 Tomcat 的RemoteIPValve内部代理列表中 -
X-Forwarded-For似乎也没有影响,所以我认为问题在于所有转发标题
Answers
我想到了。我的错误是假设networkCIDR是request.getRemoteAddr()返回的IP地址,而实际上它是我的k8s内部集群IP。这是有道理的,因为请求来自同样位于集群内部的 Apache。内部集群 IP 不在内部代理列表中,因此RemoteIPValve没有使用转发头。
通过使用RemoteIpValve中指定的默认值和我的内部集群 IP 将server.tomcat.internal-proxies属性添加到我的application.properties中,一切正常。
见https://docs.spring.io/spring-boot/docs/current/reference/html/howto-embedded-servlet-containers.html#howto-customize-tomcat-behind-a-proxy-server
更多推荐
所有评论(0)