http://www.siven.net/posts/d925bb5d.htmlhtml
***********************************************nginx
因爲要配置服務器(Nginx + Tomcat)的SSL的問題(Nginx同時監聽HTTP
和HTTPS
),可是,若是用戶訪問的是HTTPS
協議,而後Tomcat進行重定向的時候,卻變成了HTTP
.apache
在網上找了一些資料,有些是經過修改Nginx配置便可解決,也有隻對Tomcat配置進行調整解決的… 各說不一,如下對嘗試的解決過程進行記錄:tomcat
HTTP協議制轉爲https服務器
Nginx代理的配置,要添加如下內容:session
location / {
proxy_pass http://test-server;
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;
# 做用是對發送給客戶端的URL進行修改, 將http協議強制轉爲https
proxy_redirect http:// https://;
}
爲了方便測試強制轉換, http(80)、https(443)共存proxy_redirect
server {
listen 80;
listen 443 ssl;
...
}
JAVA CODE:app
HttpServletResponse resp = (HttpServletResponse)response;
resp.sendRedirect("/static/html/index.html");
使用HTTP
協議訪問nginx
代理地址以後,URL被重定向爲HTTPS
協議了, 以下圖所示:dom
固然直接使用HTTPS協議訪問, 確定也是沒有問題的,以下圖所示:post
JAVA CODE:測試
HttpServletResponse resp = (HttpServletResponse)response;
req.getRequestDispatcher("/static/html/index.html").forward(request, response);
測試結果與重定向一致, 無異常狀況;
實際應用場景中,若是要求HTTP
與HTTPS
協議共存的時候(請求的協議與響應的協議一致)就會出現HTTP
請求被強轉爲HTTPS
,嘗試將Nginx配置proxy_redirect http:// https://;
註釋,最終使用HTTPS
協議亦沒法正常跳轉;
不修改Nginx的狀況下, 僅對Tomcat配置進行調整
在server.xml
的Engine
模塊下面配置多一個如下的Valve
<Valve className="org.apache.catalina.valves.RemoteIpValve" remoteIpHeader="X-Forwarded-For" protocolHeader="X-Forwarded-Proto" protocolHeaderHttpsValue="https"/>
使用HTTPS
協議訪問時,最終被重定向到HTTP
使用HTTPS
協議訪問,轉發動做未出現問題
重定向的時候, HTTPS
協議被轉爲HTTP
,測試結果不經過。
對過程一Nginx配置進行調整註釋或刪除proxy_redirect
,最終以下:
location / {
proxy_pass http://test-server;
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;
}
參看:Tomcat配置
測試經過,不管使用HTTP訪問仍是HTTPS訪問,最終返回都是根據請求的協議進行響應,問題解決。
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream test-server {
server 10.15.16.6:8280 weight=1;
}
server {
listen 80;
listen 443 ssl;
server_name localhost;
#ssl_certificate cert.pem;
#ssl_certificate_key cert.key;
ssl_certificate server.crt;
ssl_certificate_key server.key;
# ssl_session_cache shared:SSL:1m;
#ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
location / {
proxy_pass http://test-server;
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_redirect http:// https://;
}
}
}
//處理代碼段
domainName = request.getRequestURL().toString(); String X_Forwarded_Proto = httpRequest.getHeader("X-Forwarded-Proto"); if(StringUtils.isNotBlank(X_Forwarded_Proto)){ if(X_Forwarded_Proto.toLowerCase().contains("https") && !domainName.toLowerCase().startsWith("https://")){ domainName = "https://" + domainName.substring(7); } }