[英]How to properly Redirect from Spring Boot 2.3 to HTTPS when running behind a Google Front End Load Balancer
I have a spring boot app running on GKE with the Google https load balancer via an ingress controller.我有一个 spring 启动应用程序在 GKE 上运行,并通过入口 controller 使用 Google https 负载均衡器。 The behavior I am looking for is for the Spring Boot app to redirect to https when an http request is received.
我正在寻找的行为是 Spring 引导应用程序在收到 http 请求时重定向到 https。 In Spring Boot 2.2 and earlier I was able to do this with the following code and configuration.
在 Spring Boot 2.2 及更早版本中,我可以使用以下代码和配置来执行此操作。
configuration in my application yaml我的应用程序中的配置 yaml
server:
port: 8877
use-forward-headers: true # this should make it understand X-Forwarded-Proto header
and in my Spring Security configuration I did在我的 Spring 安全配置中我做了
@Override
protected void configure(HttpSecurity http) throws Exception {
/* When the app is running on GKE traffic will come in through the
* GCP http load balancer. Which will set the X-Forwarded-Proto
* header to http or https. When the app runs on a dev machine
* these headers are not set.
*
* see https://cloud.google.com/load-balancing/docs/https/
*
* The code forces ssl if the x forwarded proto header is present
* as that indicates the app is online and accessible to the
* wider internet.
*
*/
http.requiresChannel()
.requestMatchers(r -> r.getHeader("X-Forwarded-Proto") != null)
.requiresSecure();
// more stuff omitted
}
In Spring Boot 2.3 server.use-forward-headers
was deprecated I changed my config to be在 Spring Boot 2.3
server.use-forward-headers
已弃用我将配置更改为
server:
port: 7777
forward-headers-strategy: native
tomcat:
remoteip:
protocol-header: "X-Forwarded-Proto"
remote-ip-header: "X-Forwarded-For"
I made no changes to the code that requires Secure channel.我没有对需要安全通道的代码进行任何更改。 However, when a request like https://example.com arrives at boot through the GCP load balancer it is not being recognized as a secure connection and a redirect https://example.com is sent from spring boot.
However, when a request like https://example.com arrives at boot through the GCP load balancer it is not being recognized as a secure connection and a redirect https://example.com is sent from spring boot. This causes the browser to say that an infinite redirect loop has been detected.
这会导致浏览器说已检测到无限重定向循环。
Question What is the correct way to redirect from http to https on Spring Boot 2.3 running on GKE behind a GCP load balancer configured via and Ingress controller? Question What is the correct way to redirect from http to https on Spring Boot 2.3 running on GKE behind a GCP load balancer configured via and Ingress controller?
Spring Boot is relying on Tomcat to evaluate the incoming request to determine if the request should be considered "secure". Spring 引导依赖于 Tomcat 来评估传入请求以确定该请求是否应被视为“安全”。 Tomcat remote IP valve is looking at two bits of information to evaluate if a request is secure.
Tomcat 远程 IP 阀门正在查看两位信息以评估请求是否安全。
x-forwarded-proto
http header x-forwarded-proto
http header 的值The ip address of the load balancer which is called internal proxy in tomcat config must be on the trusted list and the x-forwaded-proto
must be https
for tomcat to consider the request secure. The ip address of the load balancer which is called internal proxy in tomcat config must be on the trusted list and the
x-forwaded-proto
must be https
for tomcat to consider the request secure. Otherwise, a redirect is sent.否则,将发送重定向。
The google load balancer is sending the request with x-forwaded-proto: https
but the source ip is one from the google range 35.191.0.0/16
and 130.211.0.0/22
so tomcat was considering https requests from the GCP loadbalancer to be insecure sending back a redirect. The google load balancer is sending the request with
x-forwaded-proto: https
but the source ip is one from the google range 35.191.0.0/16
and 130.211.0.0/22
so tomcat was considering https requests from the GCP loadbalancer to be insecure发回重定向。 Thus causing the infinite redirect loop that the browser complaining about.从而导致浏览器抱怨的无限重定向循环。
Spring Boot Configures the tomcat remote ip address using using the property server.tomcat.remoteip.internal-proxies
which has default values for private ip addresses from RFC 1918 using the regex below. Spring Boot Configures the tomcat remote ip address using using the property
server.tomcat.remoteip.internal-proxies
which has default values for private ip addresses from RFC 1918 using the regex below.
10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|192\\.168\\.\\d{1,3}\\.\\d{1,3}|169\\.254\\.\\d{1,3}\\.\\d{1,3}|127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|172\\.1[6-9]{1}\\.\\d{1,3}\\.\\d{1,3}|172\\.2[0-9]{1}\\.\\d{1,3}\\.\\d{1,3}|172\\.3[0-1]{1}\\.\\d{1,3}\\.\\d{1,3}|0:0:0:0:0:0:0:1|::1
Tomcat does not know how to compare ip address ranges so the google source ips must be converted into a regex for this to work. Tomcat 不知道如何比较 ip 地址范围,因此必须将谷歌源 ips 转换为正则表达式才能工作。
server:
port: 7777
forward-headers-strategy: native
tomcat:
remoteip:
protocol-header: "X-Forwarded-Proto"
remote-ip-header: "X-Forwarded-For"
internal-proxies: ".*" # should Java regex to match ip address range of the load balancer servers. Not a best practice to trust all ip addresses.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.