http自動跳轉到https有很多種方法,如同這篇文章講的,可以:
1,通過以下自定義錯誤頁面,在頁面中嵌入javascript代碼做跳轉,有點low。
<html> <head><title>Redirecting...</title></head> <script language="JavaScript"> function redirectHttpToHttps() { var httpURL= window.location.hostname + window.location.pathname + window.location.search; var httpsURL= "https://" + httpURL; window.location = httpsURL; } redirectHttpToHttps(); </script> <body> </body> </html>
2,通過微軟的URL Rewrite組件,實際效果是服務器返回http code 301給瀏覽器,瀏覽器做跳轉。按照上面的文章提到的,在web.config中加入以下rule(或者通過IIS管理器里的URL Rewrite界面添加rule):
<rule name="HTTP to HTTPS redirect" stopProcessing="true"> <match url="(.*)" /> <conditions> <add input="{HTTPS}" pattern="off" ignoreCase="true" /> </conditions> <action type="Redirect" redirectType="Found" url="https://{HTTP_HOST}/{R:1}" /> </rule>
上面的rule也很簡單,(.*)表示所有格式的URL,{HTTPS}表示一個IIS server 變量。所有server變量以及可能的取值在這里。可以看到在用http連接時,{HTTPS}的取值是字符串“off”。{HTTP_HOST}表示web服務器的名字。
方法2在單台機器部署IIS的情況下沒問題。但是,當把阿里雲的負載均衡服務SLB扯進來,情況就有點復雜。
SLB的背后一般有多台ECS,如果SLB不開啟HTTPS端口,不在SLB上安裝證書而是在后面的每台ECS的IIS上安裝證書,開啟IIS的443端口,某些瀏覽器(比如Mac 上的Chorme)會收到證書過期的錯誤。具體原因還不是太清楚。所以只能用另外一套方案:不在每個ECS的IIS上安裝證書,而是開啟SLB的HTTPS端口,安裝證書。
但是在這種方案下,到達SLB的https請求,會被SLB轉換成http請求:

要實現http跳轉到https,我們多了一個額外的任務:區分到達IIS的http請求,是瀏覽器的http請求(要跳轉到https),還是SLB的https轉換出來的http請求(不要跳轉,返回網站內容)。想來想去,發現只能通過端口號來區分這2者,具體配置如下:
1,ECS的IIS上開放http的80和8123端口,確保與SLB的后端協議端口匹配。
2,SLB上開放兩個監聽端口,前端http 80+后端http 80, 以及前端https 443+后端http 8123。
3,URL Rewrite的rule更新成:遇到不是8123端口的http請求就跳轉至https,否則不做跳轉。
<rewrite> <rules> <rule name="HTTP to HTTPS redirect" stopProcessing="true"> <match url="(.*)"/> <conditions> <add input="{HTTPS}" pattern="off" ignoreCase="true"/> <add input="{SERVER_PORT}" pattern="^8123$" negate="true"/> </conditions> <action type="Redirect" url="https://{HTTP_HOST}/{R:1}"/> </rule> </rules> </rewrite>
現在整個流程就變成了:瀏覽器請求http 80 -> slb 轉發http 80到ECS的IIS ->URL Rewrite將請求重定向到https->slb 將 https的請求轉換為http 8123到ECS IIS-> IIS返回真正的網站內容。
只是這樣一來,IIS上要額外開一個8123的http端口,在ECS有公網地址的情況下感覺不是太安全,不知道阿里雲后續有沒有更好的解決方案。
