如何解決asp.netcore中負(fù)載均衡場(chǎng)景下http重定向https的問(wèn)題

本篇文章給大家分享的是有關(guān)如何解決asp.net core中負(fù)載均衡場(chǎng)景下http重定向https的問(wèn)題,小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說(shuō),跟著小編一起來(lái)看看吧。

成都創(chuàng)新互聯(lián)公司專業(yè)為企業(yè)提供福安網(wǎng)站建設(shè)、福安做網(wǎng)站、福安網(wǎng)站設(shè)計(jì)、福安網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、福安企業(yè)網(wǎng)站模板建站服務(wù),十余年福安做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。

上周欣喜地發(fā)現(xiàn),微軟官方終于針對(duì) asp.net core 在使用負(fù)載均衡的情況下從 http 強(qiáng)制重定向至 https 的問(wèn)題提供了解決方法。

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedProto
});var options = new RewriteOptions()
    .AddRedirectToHttpsPermanent();
app.UseRewriter(options);

但實(shí)際使用之后,欣喜變成了失望 —— 微軟對(duì)這個(gè)問(wèn)題的認(rèn)識(shí)角度和我們不一樣,造成這個(gè)方法對(duì)我們不適用,不得不繼續(xù)使用我們的土方法。

為什么會(huì)這樣?請(qǐng)看下面的分解。 

AddRedirectToHttpsPermanent 早就在 BasicMiddleware 的 RedirectToHttpsRule 中實(shí)現(xiàn)了,它的邏輯很簡(jiǎn)單 —— 判斷當(dāng)前請(qǐng)求是否是https,如果不是就進(jìn)行重定向。

if (!context.HttpContext.Request.IsHttps)
{    //...}

這個(gè)直接了當(dāng)?shù)呐袛嘣谑褂秘?fù)載均衡的場(chǎng)景下不僅不會(huì)發(fā)揮應(yīng)有的作用,而且會(huì)產(chǎn)生致命的副作用 —— 讓請(qǐng)求進(jìn)入重定向死循環(huán)(ERR_TOO_MANY_REDIRECTS)。因?yàn)椴还芸蛻舳说恼?qǐng)求是 http 還是 https ,負(fù)載均衡與后端服務(wù)器之間始終是 http(當(dāng)然你可以用https,但那是吃飽了撐著還浪費(fèi)糧食)。如果負(fù)載均衡不額外提供這個(gè)信息,在后端服務(wù)器的眼里始終只有 http 沒(méi)有 https ,http 重定向 https 根本無(wú)法實(shí)現(xiàn)。

從負(fù)載均衡的角度,為了解決這個(gè)問(wèn)題,通常會(huì)通過(guò)一個(gè)另外的專用的請(qǐng)求頭抓發(fā)這個(gè)信息,它的名字叫"X-Forwarded-Proto"。

從 asp.net core 的角度,要解決這個(gè)問(wèn)題,需要彌補(bǔ) Request.IsHttps 與 X-Forwarded-Proto 之間的鴻溝。于是微軟實(shí)現(xiàn)了上面的 app.UseForwardedHeaders() ,實(shí)際是由 ForwardedHeadersMiddleware 完成這個(gè)任務(wù) —— 根據(jù) X-Forwarded-Proto 設(shè)置 Scheme(Request.IsHttps 就是基于 Scheme 進(jìn)行判斷的)。

if (checkProto && i < forwardedProto.Length)
{    set.Scheme = forwardedProto[forwardedProto.Length - i - 1];
}

到此為止,微軟完美地解決了這個(gè)問(wèn)題,RedirectToHttpsRule 不用修改1行代碼。

但是在實(shí)際使用時(shí),我們發(fā)現(xiàn)一個(gè)大問(wèn)題,大到我們必須棄用這個(gè)看似完美的解決方法。

微軟解決 http to https 問(wèn)題的思路是這樣:只要請(qǐng)求不是 https 的,就強(qiáng)制跳轉(zhuǎn)到 https(這個(gè)沒(méi)問(wèn)題),其他一概不管,不管這個(gè)請(qǐng)求是不是來(lái)自負(fù)載均衡轉(zhuǎn)發(fā)的(這個(gè)不夠貼心)。

而我們要解決的問(wèn)題是:只有在負(fù)載均衡轉(zhuǎn)發(fā)的原始請(qǐng)求是 http 的情況下,才強(qiáng)制跳轉(zhuǎn)至 https 。比如在服務(wù)器本機(jī)訪問(wèn),比如來(lái)自其他docker容器的訪問(wèn),如果這也跳轉(zhuǎn),那每臺(tái)服務(wù)器(或者docker容器)都要部署https證書(shū),多麻煩。

一個(gè)是只要不是 https ,就跳轉(zhuǎn);一個(gè)是只有是轉(zhuǎn)發(fā)的 http ,才跳轉(zhuǎn)。 就是因?yàn)檫@個(gè)對(duì)問(wè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中負(fù)載均衡場(chǎng)景下http重定向https的問(wèn)題,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見(jiàn)到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

文章題目:如何解決asp.netcore中負(fù)載均衡場(chǎng)景下http重定向https的問(wèn)題
網(wǎng)頁(yè)地址:http://bm7419.com/article8/jjciop.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App設(shè)計(jì)、網(wǎng)站制作、電子商務(wù)網(wǎng)站營(yíng)銷、網(wǎng)站收錄、企業(yè)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

手機(jī)網(wǎng)站建設(shè)