[英]Spring Boot application with embedded Tomcat behind reverse proxy not redirecting to https when asking for /contextPath without trailing slash
This problem seems to have been asked multiple times but for this particular case I haven't found a proper solution.这个问题似乎已被多次询问,但对于这种特殊情况,我还没有找到合适的解决方案。
The application is a Spring Boot 1.5.x that uses a embedded Tomcat server and runs on Openshift.该应用程序是使用嵌入式 Tomcat 服务器并在 Openshift 上运行的 Spring Boot 1.5.x。 The latter has a Router with an HTTPS route that terminates the TLS tunnel and forwards the traffic over HTTP to the application pod.后者有一个带有 HTTPS 路由的路由器,它终止 TLS 隧道并通过 HTTP 将流量转发到应用程序 pod。 In addition it inserts the X-Forwarded- headers (including the X-Forwarded-Proto header) so that the application redirects are composed using the https protocol.此外,它插入 X-Forwarded- 标头(包括 X-Forwarded-Proto 标头),以便使用 https 协议组成应用程序重定向。
I have configured server.use-forward-headers: true
in the Spring Boot Application and tested it:我在 Spring Boot 应用程序中配置server.use-forward-headers: true
并对其进行了测试:
1) OK -> https://ocproute/myapp/ redirects 302 to my home page keeping the https protocol (the Tomcat RemoteIpValve took care of it). 1) OK -> https://ocproute/myapp/将 302 重定向到我的主页,保持 https 协议(Tomcat RemoteIpValve 处理了它)。
2) FAIL -> https://ocproute/myapp (note there's no trailing slash) redirects 302 to http://ocproute/myapp/ As you can see it changed the protocol to http since the RemoteIpValve hasn't been invoked yet). 2) FAIL -> https://ocproute/myapp (注意没有尾部斜杠)将 302 重定向到http://ocproute/myapp/正如您所看到的,它将协议更改为 http,因为尚未调用 RemoteIpValve) .
The logs show that Tomcat's Http11InputBuffer receives the request and at some point redirects it without taking into account the X-Forwarded-Proto header.日志显示 Tomcat 的 Http11InputBuffer 接收到请求,并在某些时候重定向它而不考虑 X-Forwarded-Proto 标头。
How can this be fixed?如何解决这个问题?
2019-06-03T17:31:59.230 ( - - - - - ) o.a.t.u.n.NioEndpoint DEBUG - Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@1511311d:org.apache.tomcat.util.net.NioChannel@5209052:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8080 remote=/0:0:0:0:0:0:0:1:64871]], Read direct from socket: [595]
2019-06-03T17:31:59.230 ( - - - - - ) o.a.c.h.Http11InputBuffer DEBUG - Received [GET /myapp HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
X-Forwarded-Proto: https
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en;q=0.9,en-US;q=0.8,es;q=0.7,cy;q=0.6
Cookie: JSESSIONID=4693A1F63CD3E18058F98E129D11CE57
]
...
you can set this prop in your springboot config:你可以在你的 springboot 配置中设置这个道具:
server.tomcat.use-relative-redirects=true
reference: https://github.com/spring-projects/spring-boot/issues/22908参考: https ://github.com/spring-projects/spring-boot/issues/22908
To make this work I had to disable the context root redirection customizing the Tomcat Context:为了完成这项工作,我必须禁用自定义 Tomcat 上下文的上下文根重定向:
@Configuration
class TomcatConfiguration : EmbeddedServletContainerCustomizer {
override fun customize(container: ConfigurableEmbeddedServletContainer) {
val factory = container as TomcatEmbeddedServletContainerFactory
factory.tomcatContextCustomizers = listOf(CustomCustomizer())
}
class CustomCustomizer : TomcatContextCustomizer {
override fun customize(context: Context) {
context.mapperContextRootRedirectEnabled = false
context.addServletContainerInitializer(WsSci(), null)
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.