我们有一个带有嵌入式 Tomcat 的 Spring Boot (Spring MVC) 应用,位于 Apache SSL 代理后面的专用应用服务器上。
代理服务器上的SSL端口是4433,转发到appserver上的8080端口。
所以代理服务器的 URL 是这样转发的:
https://proxyserver:4433/appname >>forward>> http://appserver:8080/
在没有代理的情况下运行时,首先发生的是
Spring Security 重定向请求,如:
http://appserver:8080/ >>redirect>> http://appserver:8080/login
显示登录表单,通过扩展 WebSecurityConfigurerAdapter
与
...
httpSecurity.formLogin().loginPage("/login") ...
...
没有代理也可以正常工作,但是使用代理需要更改重定向,
所以 Spring 应该改为重定向到相应的代理 URL,例如:
http://appserver:8080/ >>redirect>> https://proxyserver:4433/appname/login
但还没有成功。
我正在尝试应用此解决方案: 59.8 Use Tomcat behind a front-end proxy server
我们已经配置了mod_proxy在 Apache 中,并验证它发送了预期的 header :
X-Forwarded-For: xxx.xxx.xxx.xxx
X-Forwarded-Host: proxyserver
X-Forwarded-Port: 4433
X-Forwarded-Proto: https
应用程序以参数启动:
export ARG1='-Dserver.tomcat.protocol-header=x-forwarded-proto'
export ARG2='-Dserver.tomcat.remote-ip-header=x-forwarded-for'
java $ARG1 $ARG2 -jar webapp.jar
重定向仍然不起作用。
它将继续在本地重定向到客户端无法使用的 http://appserver:8080/login
。
我们还需要做些什么来让这个场景发挥作用吗?
更新
另外,我担心代理 URL 中的“/appname”部分。在应用服务器上,应用程序 Root 于“/”。当通过代理时,应如何指示 Spring 将“/appname”包含在发送回客户端的所有 URL 中?
最佳答案
前几天我也遇到了同样的问题。在对 Spring Boot 1.3 进行了一些调试后,我找到了以下解决方案。
1.您必须在 Apache 代理上设置 header :
<VirtualHost *:443>
ServerName www.myapp.org
ProxyPass / http://127.0.0.1:8080/
RequestHeader set X-Forwarded-Proto https
RequestHeader set X-Forwarded-Port 443
ProxyPreserveHost On
... (SSL directives omitted for readability)
</VirtualHost>
2. 您必须告诉您的 Spring Boot 应用程序使用这些 header 。所以把下面这行放在你的 application.properties 中(或者 Spring Boots 理解属性的任何其他地方):
server.use-forward-headers=true
如果您正确执行了这两件事,您的应用程序发送的每个重定向将不会转到 http://127.0.0.1:8080/[path]但自动发送到 https://www.myapp.com/[path]
更新 1。 关于这个主题的文档是 here .您至少应该阅读它以了解属性 server.tomcat.internal-proxies
,它定义了可信任的代理服务器的 IP 地址范围。
2021 年更新 文档移至 here . Spring Boot 配置现在有点不同了。
关于在 Apache 代理后面嵌入 Tomcat 的 Spring Boot,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25455969/