情況說明
nginx配置https,tomcat正常http接受nginx轉發。
nginx 代理https后,(java代碼redirect地址)應用redirect https變成http
原因分析:
經過nginx代理后用的spring mvc的redirect,
其中: request.getScheme() return http but not https.
瀏覽器調整的地址變成http
解決辦法:http://han.guokai.blog.163.com/blog/static/136718271201211631456811/
在代理模式下,Tomcat 如何識別用戶的直接請求(URL、IP、https還是http )?
在透明代理下,如果不做任何配置Tomcat 認為所有的請求都是 Nginx 發出來的,這樣會導致如下的錯誤結果:
request.getScheme() //總是 http,而不是實際的http或https
request.isSecure() //總是false(因為總是http)
request.getRemoteAddr() //總是 nginx 請求的 IP,而不是用戶的IP
request.getRequestURL() //總是 nginx 請求的URL 而不是用戶實際請求的 URL
response.sendRedirect( 相對url ) //總是重定向到 http 上 (因為認為當前是 http 請求)
如果程序中把這些當實際用戶請求做處理就有問題了。解決方法很簡單,只需要分別配置一下 Nginx 和 Tomcat 就好了,而不用改程序。
配置 Nginx 的轉發選項:
proxy_set_header Host $host;#設置此項會導致redirect有問題
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;
<Valve className="org.apache.catalina.valves.RemoteIpValve" remoteIpHeader="X-Forwarded-For" protocolHeader="X-Forwarded-Proto" protocolHeaderHttpsValue="https"/>
配置雙方的 X-Forwarded-Proto 就是為了正確地識別實際用戶發出的協議是 http 還是 https。X-Forwarded-For 是為了獲得實際用戶的 IP。