长情的台灯 · 年假小 Plan - ZhuGaochao ...· 1 周前 · |
小眼睛的米饭 · dotnet WinUI 3 ...· 4 天前 · |
任性的香瓜 · react-infinite-scroll- ...· 3 天前 · |
冷冷的火锅 · URL地址带拼接参数的nginx转发配置_n ...· 2 天前 · |
酷酷的冲锋衣 · nginx配置监听443端口,开启ssl协议 ...· 18 小时前 · |
暗恋学妹的铅笔 · 操作数数据类型 varchar 对于 ...· 3 周前 · |
大气的足球 · Java中的双重检查锁(double ...· 1 年前 · |
暴走的火锅 · 一文理解Kafka重复消费的原因和解决方案 ...· 1 年前 · |
谦和的皮带 · Python基础教程:Pandas知识点汇总 ...· 1 年前 · |
我们有一个Spring Boot (Spring MVC)应用程序,在Apache SSL代理后面的专用应用程序服务器上嵌入了Tomcat。
代理服务器上的SSL端口是4433,转发到应用程序服务器上的端口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
我们已经在Apache中配置了,并验证它是否发送了预期的报头:
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“部分。在应用程序服务器上,应用程序的根目录为"/“。在通过代理时,应该如何指示Spring将"/appname“包含在发送回客户端的所有URL中?
这个问题的典型解决方案是让代理处理任何需要的重写。例如,在Apache中,您可以使用 rewrite_module 和/或 headers_module 来更正头。再举一个例子,Nginx在配置上游服务器后,会自动为您处理这种情况和其他类似的情况。
回应评论:
remote_ip_header和protocol_header spring boot的配置值是什么?
让我们暂时忘记Spring Boot。嵌入式servlet容器Tomcat提供了一个称为RemoteIpValve的阀门。这个阀门是Apache remotip_module 的一个端口。这个阀门的主要目的是为了“授权和日志记录的目的”而将“发起请求的用户代理程序视为发起用户代理程序”。为了使用这个阀门,需要对其进行配置。
请查找有关此阀门 here 的更多信息。
Spring Boot通过server.tomcat.remote_ip_header和server.tomcat.protocol_header属性方便地支持通过application.properties配置该阀。
在某种程度上,您的代理看起来很好,后端应用也是如此,但它似乎没有看到
RemoteIpValve
修改的请求。
RemoteIpValve
的默认行为包括代理IP地址的模式匹配(作为安全检查),并且它只修改它认为来自有效代理的请求。Spring Boot中的模式缺省为一组众所周知的内部IP地址,如
10.*.*.*
和
192.168.*.*
,因此如果您的代理不在其中一个上,您需要显式地配置它,例如
server.tomcat.internal-proxies=172\\.17\\.\\d{1,3}\\.\\d{1,3}|127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}
(使用属性文件格式,这意味着您必须对反斜杠进行双重转义)。
如果您设置了以下内容,则可以查看
RemoteIpValve
中正在发生的情况
logging.level.org.apache.catalina.valves.RemoteIpValve=DEBUG
或者在其中设置断点。
我使用haproxy作为负载均衡器的情况与下面的配置完全相同,这对我很有效。唯一的问题是客户端IP在
request.getRemoteAddr()
中,而不在
"X-Forwarded-For"
报头中
frontend www
bind *:80
bind *:443 ssl crt crt_path
redirect scheme https if !{ ssl_fc }
mode http
default_backend servers
backend servers
mode http
balance roundrobin
option forwardfor
server S1 host1:port1 check
server S2 host2:port2 check
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
在application.properties中:
server.use-forward-headers=true
你有没有试过设置
server.context-path=/appname
在Spring Boot里?
尝试设置重写规则,如: https://proxyserver:4433/appname >>forward>> http://appserver:8080/appname
然后将应用程序上下文设置为"appname“server.context-path=/appname
因此,在本地,您可以通过 http://appserver:8080/appname 运行,也可以通过反向代理通过 https://proxyserver:4433/appname 访问
由于我使用的是JBOSS,所以jboss的standalone.xm发生了变化:
<http-listener name="default" socket-binding="http" redirect-socket="https" proxy-address-forwarding="true" enable-http2="true"/>
Tomcat将具有类似的配置,以通知Tomcat ( proxy - address - forwarding ="true")遵守代理转发地址。