在Apache代理后面嵌入Tomcat的Spring-boot

Rop*_*Rop 25 spring tomcat reverse-proxy spring-security spring-boot

我们在Apache SSL代理后面的专用appserver上有一个带有嵌入式Tomcat的spring-boot/spring-mvc应用程序.

代理服务器上的SSL端口为4433,转发到应用服务器上的端口8080.

所以代理服务器的URL转发如下:

https://proxyserver:4433/appname   >>forward>>   http://appserver:8080/
Run Code Online (Sandbox Code Playgroud)

运行WITHOUT代理时,首先发生的事情是
spring-security重定向请求,如:

http://appserver:8080/   >>redirect>>   http://appserver:8080/login
Run Code Online (Sandbox Code Playgroud)

以显示登录表单,通过扩展WebSecurityConfigurerAdapter

  ...
  httpSecurity.formLogin().loginPage("/login") ...
  ...
Run Code Online (Sandbox Code Playgroud)

它在没有代理的情况下工作正常,但是WITH代理需要更改重定向,因此Spring应该重定向到相应的代理URL,如:

http://appserver:8080/   >>redirect>>   https://proxyserver:4433/appname/login
Run Code Online (Sandbox Code Playgroud)

但还没有成功.

我正在尝试应用此解决方案:

http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#howto-use-tomcat-behind-a-proxy-server(59.8 在前端代理服务器后面使用Tomcat)

我们在Apache中配置了mod_proxy,并验证它是否发送了预期的头文件:

X-Forwarded-For: xxx.xxx.xxx.xxx
X-Forwarded-Host: proxyserver
X-Forwarded-Port: 4433
X-Forwarded-Proto: https
Run Code Online (Sandbox Code Playgroud)

应用程序以参数启动:

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
Run Code Online (Sandbox Code Playgroud)

仍然重定向不起作用.

它将保持本地重定向, http://appserver:8080/login客户端无法使用.

我们需要做些什么来使这个场景有效吗?

编辑:此外,我担心代理URL中的"/ appname"部分.在appserver上,应用程序以"/"为根.在通过代理时,应该如何指示spring// appname应该包含在发送回客户端的所有URL中?

Igo*_*hin 25

前几天我遇到了同样的问题.经过Spring Boot 1.3的一些调试后,我找到了以下解决方案.

1.您必须在Apache代理上设置标头:

<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>
Run Code Online (Sandbox Code Playgroud)

2.您必须告诉Spring Boot应用程序使用这些标头.所以将以下行放在application.properties(或Spring Boots了解属性的任何其他地方)中:

server.use-forward-headers=true
Run Code Online (Sandbox Code Playgroud)

如果你正确地做了这两件事,你的应用程序发送的每个重定向都不会转到http://127.0.0.1:8080/[path],而是自动转到https://www.myapp.com/[path]

更新1.有关此主题的文档在此处.您应该至少阅读它以了解server.tomcat.internal-proxies定义可信任的代理服务器的IP地址范围的属性.

  • `server.use-forward-headers = true`适用于Google Cloud Load Balancer (2认同)

Dav*_*yer 5

您的代理看起来不错,后端应用程序也是如此,在某种程度上,但它似乎没有看到RemoteIpValve修改后的请求。的默认行为RemoteIpValve包括代理 IP 地址的模式匹配(作为安全检查),它只修改它认为来自有效代理的请求。Spring Boot 中的模式默认为一组众所周知的内部 IP 地址,例如10.*.*.*and 192.168.*.*,因此如果您的代理不在其中之一,则您需要显式配置它,例如

server.tomcat.internal-proxies=172\\.17\\.\\d{1,3}\\.\\d{1,3}|127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}
Run Code Online (Sandbox Code Playgroud)

(使用属性文件格式,这意味着您必须对反斜杠进行双重转义)。

RemoteIpValve如果你设置,你可以看到发生了什么

logging.level.org.apache.catalina.valves.RemoteIpValve=DEBUG
Run Code Online (Sandbox Code Playgroud)

或在其中设置断点。