ASP.NET Core 的 https redirection middleware

  • 1045
  • 0

在 ASP.NET Core 2.1 中多了一個新的 middleware 用來將 http 連線重新導向到 https,這是一個任務單純且重要的 middleware,請興趣的讀者可看內文.

在以前的文章裡,我曾寫過 ASP.NET Core middleware 文章,裡面有描述的主要是 middleware 的用途和用法.在 ASP.NET Core 版本演進的過程中,ASP.NET Core 團隊也陸續加了些好用的 middleware.在 ASP.NET Core 2.1 版裡也多了一個新的 middleware - https redirection.故名思義就知道這新的 middleware 就是將非 https 的連線重新導向成 https,這種工作用 middleware 的方式呈現是非常好的 middleware 範例.

Https redirection middleware 的原始碼存在於 https://github.com/aspnet/BasicMiddleware/blob/release/2.1/src/Microsoft.AspNetCore.HttpsPolicy/HttpsRedirectionMiddleware.cs 

整個原始碼的長度並不長,主要的內容在 Invoke() method,在這裡可以看到如何辦別連線是不是 https,並且辦別不是 https 之後,該如何導向到 https.其實內容主要就是辦別 HttpContext 的 Request 內容,一旦發現 Request 內容的 port 不是 443 或者不是你所定義的 https port 時,此時就不會到下一個 middleware 繼續處理這個 request,而是會建立一個新的 uri ,直接在 HttpContext 的 Response 內容寫入新的 uri,讓 browser 下次可以用新的 uri.

預設上,https port 是 443.除此之外,你也可以定義自訂的 https port 以用在測試環境或其他情況下.自訂 https port 最簡單的方式是寫入一個 HTTPS_PORT 的環境變數到你的執行環境裡,也記得用 IConfiguration 將環境變數讀入到 ASP.NET Core 所用的 configuration,這樣才能讓 https redirection middleware 讀取到正確的 HTTPS_PORT.有關細節的做法,你可以參考 https redirection middleware 的原始碼.

除了透過環境變數來設定 https port 以外,另外還有一種方法是設定 IServerAddressFeature,這種方式是用寫程式的方式來告訴你的 webhost builder 什麼 port 才是 https port.參考以下的程式碼:

        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            
            services.Configure<HttpsRedirectionOptions>(options =>
            {
                options.RedirectStatusCode = StatusCodes.Status301MovedPermanently;
                options.HttpsPort = 44343;
            });
            
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }

不論是用何種方式,在 webhost builder 的 Configure() 裡都記得要加上 https redirection middleware.

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseHttpsRedirection();  // https redirection middleware
            app.UseStaticFiles();
            app.UseCookiePolicy();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }

最後,在範本裡也為這個功能加上了選項.當你安裝好 .Net Core 2.1 版本後,在 Visual Studio 2017 裡開始新的 ASP.NET Core 專案範本,將 ASP.NET Core 版本切換到 2.1,你便看到看專案範本視窗下多了一個 Configure for HTTPS 的選項.

這個範本開起來後,你就會看到 app.UseHttpsRedirection(); 已經加在 webhost builder 的 Configure() method 裡,而所採用的 https port 將會依照你當下的 Visual Studio 2017 的環境設定.有關預設的設定,可以開始專案裡 Properties 下有個檔名為 launchSettings.json.裡面定義了當你用 IISExpress 的方式啟動該專案時,它所採用的 https port 是那一個號碼 (參考該 json 裡 sslPort 元素的值).

Hope it helps,