在Apache代理后面具有嵌入式Tomcat的Spring Boot
我们在Apache SSL代理后面的专用应用服务器上有一个带有嵌入式Tomcat的Spring Boot(Spring MVC)应用.
We have a Spring Boot (Spring MVC) app with embedded Tomcat on a dedicated appserver behind an Apache SSL proxy.
代理服务器上的SSL端口为4433,转发到应用服务器上的端口8080.
The SSL port on the proxy server is 4433, forwarding to port 8080 on the appserver.
因此,代理服务器的URL正在转发,例如:
So the URL to the proxy server is forwarding like:
https://proxyserver:4433/appname >>forward>> http://appserver:8080/
运行WITHOUT代理时,首先发生的事情是
Spring Security重定向请求,例如:
When running WITHOUT proxy, the first thing that happens is that
Spring Security redirects the request, like:
http://appserver:8080/ >>redirect>> http://appserver:8080/login
通过扩展WebSecurityConfigurerAdapter
并显示
...
httpSecurity.formLogin().loginPage("/login") ...
...
在没有代理的情况下可以正常工作,但是在使用代理的情况下,需要更改重定向,
因此,Spring应该重定向到相应的代理URL,例如:
It works fine without the proxy, but WITH proxy the redirect needs to be changed,
so Spring should instead redirect to the corresponding proxy URL, like:
http://appserver:8080/ >>redirect>> https://proxyserver:4433/appname/login
但没有成功.
I am trying to apply this solution: 59.8 Use Tomcat behind a front-end proxy server
我们已经在Apache中配置了 mod_proxy ,并对其进行了验证发送预期的标头:
We have configured mod_proxy in Apache, and verified that it sends the expected headers:
X-Forwarded-For: xxx.xxx.xxx.xxx
X-Forwarded-Host: proxyserver
X-Forwarded-Port: 4433
X-Forwarded-Proto: https
应用程序使用以下参数启动:
The application is started with parameters:
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
.
It will keep redirecting locally, to http://appserver:8080/login
which is not available to the clients.
要使此方案正常工作,我们还需要做其他事情吗?
Is there anything else we need to do to make this scenario work?
此外,我担心"/appname"部分包含在代理网址中.在应用服务器上,应用程序植根于"/".应该如何指示Spring"/appname"?通过代理发送给客户端的所有URL中都应包含该地址?
Also, I am concerned about the "/appname" part in the proxy URL. On the appserver the application is rooted at "/". How should Spring be instructed that "/appname" should be included in all URLs sent back to the clients, when going thru the proxy?
前几天我遇到了同样的问题.在对Spring Boot 1.3进行一些调试之后,我发现了以下解决方案.
I had the same problem the other day. After some debugging of Spring Boot 1.3 I found the following solution.
1..您必须在Apache代理上设置标头:
1. You have to setup the headers on your Apache proxy:
<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应用程序使用这些标头.因此,将以下行放在application.properties中(或Spring Boots可以理解属性的任何其他位置):
2. You have to tell your Spring Boot app to use these headers. So put the following line in your application.properties (or any other place where Spring Boots understands properties):
server.use-forward-headers=true
如果您正确地完成了这两项操作,则应用程序发送的每个重定向将不转到https://www.myapp.com/[路径]
If you do these two things correctly, every redirect your application sends will not go to http://127.0.0.1:8080/[path] but automatically to https://www.myapp.com/[path]
Update 1. The documentation about this topic is here. You should read it at least to be aware of the property server.tomcat.internal-proxies
which defines the range of IP-addresses for proxy servers that can be trusted.