场景:
nginx配置为https,应用服务器tomcat或jetty配置为http,客户端通过nginx代理服务器访问应用服务器。
问题:
当客户端通过nginx访问时,应用服务器java重定向变为http。
原因:
在nginx代理时,当应用服务器不做配置时,则认为所有的请求都来至于nginx的http请求,导致通过request和response获取到错误信息:
request.getScheme() //总是http,而不是客户端的https
request.isSecure() //总是false(因为是http)
request.getRemoteAddr() //总是nginx请求的IP,而不是客户端的IP
request.getRequestURL() //总是nginx请求的URL 而不是客户端实际请求的URL
response.sendRedirect( 相对url ) //总是重定向到http上(因为认为当前是nginx发起的http请求)
解决方法:
1、nginx配置
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header V-Insecurity Yes;
2、应用服务器配置
tomcat:
在server.xml文件的Engine模块下新增配置:
<Valve className="org.apache.catalina.valves.RemoteIpValve" remoteIpHeader="X-Forwarded-For" protocolHeader="X-Forwarded-Proto" protocolHeaderHttpsValue="https"/>
作用:指示tomcat从HTTP头信息中去获取协议信息(而非从HttpServletRequest中获取)
jetty:
打开jetty.xml文件的httpConfig节点的addCustomizer配置
<New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
<Set name="secureScheme">https</Set>
<Set name="securePort"><Property name="jetty.secure.port" default="8443" /></Set>
<Set name="outputBufferSize"><Property name="jetty.output.buffer.size" default="32768" /></Set>
<Set name="outputAggregationSize"><Property name="jetty.output.aggregation.size" default="8192" /></Set>
<Set name="requestHeaderSize"><Property name="jetty.request.header.size" default="8192" /></Set>
<Set name="responseHeaderSize"><Property name="jetty.response.header.size" default="8192" /></Set>
<Set name="sendServerVersion"><Property name="jetty.send.server.version" default="true" /></Set>
<Set name="sendDateHeader"><Property name="jetty.send.date.header" default="false" /></Set>
<Set name="headerCacheSize">512</Set>
<Set name="delayDispatchUntilContent"><Property name="jetty.delayDispatchUntilContent" default="false"/></Set>
<!-- Uncomment to enable handling of X-Forwarded- style headers
-->
<Call name="addCustomizer">
<Arg><New class="org.eclipse.jetty.server.ForwardedRequestCustomizer"/></Arg>
</Call>
</New>
作用:可以识别X-Forwarded- 形式的header