本篇文章給大家分享的是有關如何解決asp.net core中負載均衡場景下http重定向https的問題,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
成都創(chuàng)新互聯(lián)公司專業(yè)為企業(yè)提供福安網(wǎng)站建設、福安做網(wǎng)站、福安網(wǎng)站設計、福安網(wǎng)站制作等企業(yè)網(wǎng)站建設、網(wǎng)頁設計與制作、福安企業(yè)網(wǎng)站模板建站服務,十余年福安做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡服務。
上周欣喜地發(fā)現(xiàn),微軟官方終于針對 asp.net core 在使用負載均衡的情況下從 http 強制重定向至 https 的問題提供了解決方法。
app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedProto });var options = new RewriteOptions() .AddRedirectToHttpsPermanent(); app.UseRewriter(options);
但實際使用之后,欣喜變成了失望 —— 微軟對這個問題的認識角度和我們不一樣,造成這個方法對我們不適用,不得不繼續(xù)使用我們的土方法。
為什么會這樣?請看下面的分解。
AddRedirectToHttpsPermanent 早就在 BasicMiddleware 的 RedirectToHttpsRule 中實現(xiàn)了,它的邏輯很簡單 —— 判斷當前請求是否是https,如果不是就進行重定向。
if (!context.HttpContext.Request.IsHttps) { //...}
這個直接了當?shù)呐袛嘣谑褂秘撦d均衡的場景下不僅不會發(fā)揮應有的作用,而且會產(chǎn)生致命的副作用 —— 讓請求進入重定向死循環(huán)(ERR_TOO_MANY_REDIRECTS)。因為不管客戶端的請求是 http 還是 https ,負載均衡與后端服務器之間始終是 http(當然你可以用https,但那是吃飽了撐著還浪費糧食)。如果負載均衡不額外提供這個信息,在后端服務器的眼里始終只有 http 沒有 https ,http 重定向 https 根本無法實現(xiàn)。
從負載均衡的角度,為了解決這個問題,通常會通過一個另外的專用的請求頭抓發(fā)這個信息,它的名字叫"X-Forwarded-Proto"。
從 asp.net core 的角度,要解決這個問題,需要彌補 Request.IsHttps 與 X-Forwarded-Proto 之間的鴻溝。于是微軟實現(xiàn)了上面的 app.UseForwardedHeaders() ,實際是由 ForwardedHeadersMiddleware 完成這個任務 —— 根據(jù) X-Forwarded-Proto 設置 Scheme(Request.IsHttps 就是基于 Scheme 進行判斷的)。
if (checkProto && i < forwardedProto.Length) { set.Scheme = forwardedProto[forwardedProto.Length - i - 1]; }
到此為止,微軟完美地解決了這個問題,RedirectToHttpsRule 不用修改1行代碼。
但是在實際使用時,我們發(fā)現(xiàn)一個大問題,大到我們必須棄用這個看似完美的解決方法。
微軟解決 http to https 問題的思路是這樣:只要請求不是 https 的,就強制跳轉(zhuǎn)到 https(這個沒問題),其他一概不管,不管這個請求是不是來自負載均衡轉(zhuǎn)發(fā)的(這個不夠貼心)。
而我們要解決的問題是:只有在負載均衡轉(zhuǎn)發(fā)的原始請求是 http 的情況下,才強制跳轉(zhuǎn)至 https 。比如在服務器本機訪問,比如來自其他docker容器的訪問,如果這也跳轉(zhuǎn),那每臺服務器(或者docker容器)都要部署https證書,多麻煩。
一個是只要不是 https ,就跳轉(zhuǎn);一個是只有是轉(zhuǎn)發(fā)的 http ,才跳轉(zhuǎn)。 就是因為這個對問題理解的差異,我們不得不放棄采用微軟的官方解決方法,繼續(xù)使用我們不太優(yōu)雅的土方法。
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);
以上就是如何解決asp.net core中負載均衡場景下http重定向https的問題,小編相信有部分知識點可能是我們?nèi)粘9ぷ鲿姷交蛴玫降?。希望你能通過這篇文章學到更多知識。更多詳情敬請關注創(chuàng)新互聯(lián)行業(yè)資訊頻道。