我最近将我的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
似乎也没有影响,所以我认为问题在于所有转发标题答案 0 :(得分:3)
我明白了。我的错误是假设networkCIDR
是request.getRemoteAddr()
返回的IP地址,而它实际上是我的k8s内部集群IP。这是有意义的,因为请求来自Apache,它也在集群内部。内部群集IP不在内部代理列表中,因此RemoteIPValve
未使用转发头。
通过使用server.tomcat.internal-proxies
和我的内部群集IP中指定的默认值将application.properties
属性添加到RemoteIpValve
,一切正常。