昨天解決了在阿里雲負載均衡上部署https證書的問題(詳見一個空行引發的阿里雲負載均衡上部署https證書的問題),並完成了部署,負載均衡的監聽配置是這樣的:html
用戶與負載均衡之間走https協議,負載均衡與後端服務器之間走http協議,這樣的好處之一是後端服務器不用一臺臺安裝證書了。web
今天早上準備實現當用戶以http訪問站點時自動跳轉爲https訪問,因而想固然地在後端web服務器中添加了一條以下的URL重寫規則(IIS URL Rewrite Module):後端
<rewrite> <rules> <rule name="redirect_http_to_https" stopProcessing="true"> <match url="^$" /> <conditions> <add input="{HTTPS}" pattern="^OFF$" /> <add input="{REMOTE_ADDR}" pattern="^127.0.0.1$" negate="true" /> </conditions> <action type="Redirect" url="https://{HTTP_HOST}/" redirectType="Temporary" /> </rule> </rules> </rewrite>
結果http的確跳轉爲https,可是直接以https訪問,Chrome瀏覽器卻出現「Redirect too many times」的錯誤,https訪問居然也會跳轉,怎麼回事?瀏覽器
停下來一想,立馬恍然大悟:本身早上還沒睡醒,忘了負載均衡與後端服務器之間始終走的是http協議,無論用戶是http訪問仍是https訪問,後端服務器收到的都是http請求,在後端服務器上根本區分不出用戶用的是http仍是https,根本沒法經過上面的URL重寫實現。服務器
向阿里雲反饋這個狀況,從客服那獲得的一個解決方法是在後端服務器上也部署https證書,讓負載均衡與後端服務器之間也走https協議。app
在衆多後端服務器上一臺臺部署證書,好麻煩;僅僅爲了重定向而讓負載均衡與後端服務器的通訊協議由http改成https,好浪費。最經濟環保的解決方法是負載均衡直接支持URL重寫,我只需在負載均衡控制檯添加一條URL重寫規則。已經向阿里雲提出了建議,但願能儘早實現。負載均衡
更新:後來阿里雲實現了:「經過X-Forwarded-Proto頭字段獲取SLB的監聽協議」ide
在ASP.NET Core中的實現代碼以下:post
public class RedirectToProxiedHttpsRule : RedirectToHttpsRule { public RedirectToProxiedHttpsRule() { base.StatusCode = StatusCodes.Status301MovedPermanently; base.SSLPort = null; } public override void ApplyRule(RewriteContext context) { var key = "X-Forwarded-Proto"; var request = context.HttpContext.Request; if (request.Headers.ContainsKey(key)) { if (request.Headers[key].FirstOrDefault() == "http") { base.ApplyRule(context); } } } }
public class Startup { public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { var rewriteOptions = new RewriteOptions(); rewriteOptions.Rules.Add(new RedirectToProxiedHttpsRule()); app.UseRewriter(rewriteOptions); } }