昨天解决了在阿里云负载均衡上部署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); } }