asp.net core中负载均衡场景下http重定向https的问题
2017-06-19 07:25
615 查看
上周欣喜地发现,微软官方终于针对 asp.net core 在使用负载均衡的情况下从 http 强制重定向至 https 的问题提供了解决方法。
但实际使用之后,欣喜变成了失望 —— 微软对这个问题的认识角度和我们不一样,造成这个方法对我们不适用,不得不继续使用我们的土方法。
为什么会这样?请看下面的分解。
AddRedirectToHttpsPermanent 早就在 BasicMiddleware 的 RedirectToHttpsRule 中实现了,它的逻辑很简单 —— 判断当前请求是否是https,如果不是就进行重定向。
这个直接了当的判断在使用负载均衡的场景下不仅不会发挥应有的作用,而且会产生致命的副作用 —— 让请求进入重定向死循环(ERR_TOO_MANY_REDIRECTS)。因为不管客户端的请求是 http 还是 https ,负载均衡与后端服务器之间始终是 http(当然你可以用https,但那是吃饱了撑着还浪费粮食)。如果负载均衡不额外提供这个信息,在后端服务器的眼里始终只有 http 没有 https ,http 重定向 https 根本无法实现。
从负载均衡的角度,为了解决这个问题,通常会通过一个另外的专用的请求头抓发这个信息,它的名字叫"X-Forwarded-Proto"。
从 asp.net core 的角度,要解决这个问题,需要弥补 Request.IsHttps 与 X-Forwarded-Proto 之间的鸿沟。于是微软实现了上面的 app.UseForwardedHeaders() ,实际是由 ForwardedHeadersMiddleware 完成这个任务 —— 根据 X-Forwarded-Proto 设置 Scheme(Request.IsHttps 就是基于 Scheme 进行判断的)。
到此为止,微软完美地解决了这个问题,RedirectToHttpsRule 不用修改1行代码。
但是在实际使用时,我们发现一个大问题,大到我们必须弃用这个看似完美的解决方法。
微软解决 http to https 问题的思路是这样:只要请求不是 https 的,就强制跳转到 https(这个没问题),其他一概不管,不管这个请求是不是来自负载均衡转发的(这个不够贴心)。
而我们要解决的问题是:只有在负载均衡转发的原始请求是 http 的情况下,才强制跳转至 https 。比如在服务器本机访问,比如来自其他docker容器的访问,如果这也跳转,那每台服务器(或者docker容器)都要部署https证书,多麻烦。
一个是只要不是 https ,就跳转;一个是只有是转发的 http ,才跳转。 就是因为这个对问题理解的差异,我们不得不放弃采用微软的官方解决方法,继续使用我们不太优雅的土方法。
RedirectToProxiedHttpsRule
RewriteOptionsExtensions
在 Startup 中使用
原文地址:http://www.cnblogs.com/dudu/p/7044923.html
.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注
app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedProto });var options = new RewriteOptions() .AddRedirectToHttpsPermanent(); app.UseRewriter(options);
但实际使用之后,欣喜变成了失望 —— 微软对这个问题的认识角度和我们不一样,造成这个方法对我们不适用,不得不继续使用我们的土方法。
为什么会这样?请看下面的分解。
AddRedirectToHttpsPermanent 早就在 BasicMiddleware 的 RedirectToHttpsRule 中实现了,它的逻辑很简单 —— 判断当前请求是否是https,如果不是就进行重定向。
if (!context.HttpContext.Request.IsHttps) { //...}
这个直接了当的判断在使用负载均衡的场景下不仅不会发挥应有的作用,而且会产生致命的副作用 —— 让请求进入重定向死循环(ERR_TOO_MANY_REDIRECTS)。因为不管客户端的请求是 http 还是 https ,负载均衡与后端服务器之间始终是 http(当然你可以用https,但那是吃饱了撑着还浪费粮食)。如果负载均衡不额外提供这个信息,在后端服务器的眼里始终只有 http 没有 https ,http 重定向 https 根本无法实现。
从负载均衡的角度,为了解决这个问题,通常会通过一个另外的专用的请求头抓发这个信息,它的名字叫"X-Forwarded-Proto"。
从 asp.net core 的角度,要解决这个问题,需要弥补 Request.IsHttps 与 X-Forwarded-Proto 之间的鸿沟。于是微软实现了上面的 app.UseForwardedHeaders() ,实际是由 ForwardedHeadersMiddleware 完成这个任务 —— 根据 X-Forwarded-Proto 设置 Scheme(Request.IsHttps 就是基于 Scheme 进行判断的)。
if (checkProto && i < forwardedProto.Length) { set.Scheme = forwardedProto[forwardedProto.Length - i - 1]; }
到此为止,微软完美地解决了这个问题,RedirectToHttpsRule 不用修改1行代码。
但是在实际使用时,我们发现一个大问题,大到我们必须弃用这个看似完美的解决方法。
微软解决 http to https 问题的思路是这样:只要请求不是 https 的,就强制跳转到 https(这个没问题),其他一概不管,不管这个请求是不是来自负载均衡转发的(这个不够贴心)。
而我们要解决的问题是:只有在负载均衡转发的原始请求是 http 的情况下,才强制跳转至 https 。比如在服务器本机访问,比如来自其他docker容器的访问,如果这也跳转,那每台服务器(或者docker容器)都要部署https证书,多麻烦。
一个是只要不是 https ,就跳转;一个是只有是转发的 http ,才跳转。 就是因为这个对问题理解的差异,我们不得不放弃采用微软的官方解决方法,继续使用我们不太优雅的土方法。
RedirectToProxiedHttpsRule
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); } } } }
RewriteOptionsExtensions
public static class RewriteOptionsExtensions { public static RewriteOptions AddRedirectForwardedHttpToHttps(this RewriteOptions options) { options.Rules.Add(new RedirectToProxiedHttpsRule()); return options; } }
在 Startup 中使用
var options = new RewriteOptions() .AddRedirectForwardedHttpToHttps(); app.UseRewriter(options);
原文地址:http://www.cnblogs.com/dudu/p/7044923.html
.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注
相关文章推荐
- asp.net core中负载均衡场景下http重定向https的问题
- ASP.NET Core 使用 URL Rewrite 中间件实现 HTTP 重定向到 HTTPS
- https,https的本地测试环境搭建,asp.net结合https的代码实现,http网站转换成https网站之后遇到的问题
- 使用阿里云负载均衡遭遇的http重定向https的问题
- 问题:调用 ASP.Net Core WebAPI的HTTP POST方法时,从 [FromBody] 中读取的 MongoDB GeoJsonObjectModel成员总是null
- https,https的本地测试环境搭建,asp.net结合https的代码实现,http网站转换成https网站之后遇到的问题
- https,https的本地测试环境搭建,asp.net结合https的代码实现,http网站转换成https网站之后遇到的问题
- https,https的本地测试环境搭建,asp.net结合https的代码实现,http网站转换成https网站之后遇到的问题
- https,https的本地测试环境搭建,asp.net结合https的代码实现,http网站转换成https网站之后遇到的问题
- https,https的本地测试环境搭建,asp.net结合https的代码实现,http网站转换成https网站之后遇到的问题
- ASP.NET Core Web API处理HttpResponseMessage类型返回值的问题
- 【转】https,https的本地测试环境搭建,asp.net结合https的代码实现,http网站转换成https网站之后遇到的问题
- 用ASP.NET做项目,本本上的系统是XP,网上下载了IIS6,安装完后出现HTTP500问题,解决之.接着出现了浏览页面时跳出登陆框让输用户名及密码,GOOGLE了一下,原来是权限不够,解决方法
- ASP.net HTTP/HTTPS自动切换
- Asp.net使用httpHandlers报404的问题
- asp.net url重写重定向问题
- Win7部署asp.net网站问题---HTTP 错误 500.0 - Internal Server Error 调用 LoadLibraryEx 失败
- iis7 发布mvc3 遇到的HTTP错误 403.14-Forbidden Web 服务器被配置为不列出此目录的内容及Login on failed for "IIS APPPOOL\ASP.NET v4.0"问题
- 关于asp.net HttpUtility.UrlDecode解码问题
- ASP.NET中前台javascript与后台c#函数相互调用问题(1)http://hi.baidu.com/xuexiang516168/blog/item/90f2bc4bc316372908f7eff4.html