在 ASP.NET Core 中強制執行 HTTPS

作者 David GalvanRick Anderson

本文件說明如何:

  • 針對所有要求都要求 HTTPS。
  • 將所有 HTTP 要求都重新導向至 HTTPS。

任何 API 都無法防止用戶端在第一個要求時傳送敏感性資料。

警告

API 專案

請勿在接收敏感性資訊的 Web API 上使用 RequireHttpsAttributeRequireHttpsAttribute 會使用 HTTP 狀態碼,將瀏覽器從 HTTP 重新導向至 HTTPS。 API 用戶端可能無法了解或遵循從 HTTP 重新導向至 HTTPS。 此類用戶端可能會透過 HTTP 傳送資訊。 Web API 應該:

  • 不接聽 HTTP。
  • 關閉狀態碼為 400 (錯誤的要求) 且未提供要求的連線。

若要停用 API 中的 HTTP 重新導向,請設定 ASPNETCORE_URLS 環境變數或使用 --urls 命令列旗標。 如需詳細資訊,請參閱 在 ASP.NET Core 中使用多個環境,以及 8 種方式,以由 Andrew Lock 設定 ASP.NET Core 應用程式的 URL。

HSTS 和 API 專案

預設 API 專案不包含 HSTS,因為 HSTS 通常是僅限瀏覽器的指示。 其他呼叫者,例如電話或傳統型應用程式,請勿遵循指示。 即使在瀏覽器內,透過 HTTP 對 API 的單一驗證呼叫也會對不安全的網路造成風險。 安全的方法是將 API 專案設定為只接聽並透過 HTTPS 回應。

HTTP 重新導向至 HTTPS 會導致 CORS 預檢要求上的 ERR_INVALID_REDIRECT

使用 HTTP 向端點提出要求,這些 HTTP 會因為使用 ERR_INVALID_REDIRECT on the CORS preflight requestUseHttpsRedirection 失敗而重新導向至 HTTPS。

API 專案可以拒絕 HTTP 要求,而不是使用 UseHttpsRedirection 來將要求重新導向至 HTTPS。

需要 HTTPS

我們建議生產 ASP.NET Core Web 應用程式使用:

  • 用來將 HTTP 要求重新導向至 HTTPS 的 HTTPS 重新導向中介軟體 (UseHttpsRedirection)。
  • 用來將 HTTP 嚴格的傳輸安全性通訊協定 (HSTS) 標頭傳送給用戶端的 HSTS 中介軟體 (UseHsts)。

注意

部署在反向 Proxy 設定中的應用程式可讓 Proxy 處理連線安全性 (HTTPS)。 如果 Proxy 也處理 HTTPS 重新導向,則不需要使用 HTTPS 重新導向中介軟體。 如果 Proxy 伺服器也處理寫入 HSTS 標頭 (例如 IIS 10.0 (1709) 或更新版本中的原生 HSTS 支援),則應用程式不需要 HSTS 中介軟體。 如需詳細資訊,請參閱在專案建立時選擇退出 HTTPS/HSTS

UseHttpsRedirection

下列程式碼會在 Program.cs 檔案中呼叫 UseHttpsRedirection

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

上述醒目提示的程式碼:

我們建議使用暫時重新導向,而不是永久重新導向。 連結快取可能會導致開發環境中不穩定的行為。 如果您想要在應用程式位於非開發環境中時傳送永久重新導向狀態碼,請參閱在生產環境中設定永久重新導向一節。 我們建議使用 HSTS 向用戶端發出訊號,指出只應將安全的資源要求傳送至應用程式 (僅限生產環境中)。

連接埠組態

中介軟體必須可使用連接埠,才能將不安全的要求重新導向至 HTTPS。 如果沒有可用的連接埠:

  • 不會重新導向至 HTTPS。
  • 中介軟體會記錄警告「無法判斷要重新導向的 HTTPS 連接埠。」

使用下列任何方法指定 HTTPS 連接埠:

  • 設定 HttpsRedirectionOptions.HttpsPort

  • 設定https_port主機設定

    • 在主機設定中。

    • 藉由設定 ASPNETCORE_HTTPS_PORTS 環境變數。

    • 藉由在 appsettings.json 中新增最上層項目:

      {
        "https_port": 443,
        "Logging": {
          "LogLevel": {
            "Default": "Information",
            "Microsoft.AspNetCore": "Warning"
          }
        },
        "AllowedHosts": "*"
      }
      
  • 使用 ASPNETCORE_URLS 環境變數,指出具有安全配置的連接埠。 環境變數會設定伺服器。 中介軟體會透過 IServerAddressesFeature 間接探索 HTTPS 連接埠。 此方法不適用於反向 Proxy 部署。

  • ASP.NET Core Web 範本會針對 Kestrel 和 IIS Express 在 Properties/launchsettings.json 中設定 HTTPS URL。 launchsettings.json 只會用於本機電腦。

  • Kestrel 伺服器或 HTTP.sys 伺服器的公開邊緣部署設定 HTTPS URL 端點。 應用程式只會使用一個 HTTPS 連接埠。 中介軟體會透過 IServerAddressesFeature 探索連接埠。

注意

在反向 Proxy 設定中執行應用程式時,IServerAddressesFeature 無法使用。 使用本節所述的其中一種其他方法來設定連接埠。

邊緣部署

KestrelHTTP.sys 作為公開邊緣伺服器使用時,Kestrel 或 HTTP.sys 必須設定為接聽兩者:

  • 重新導向用戶端所在的安全連接埠 (通常在生產環境中為 443,在開發環境中為 5001)。
  • 不安全的連接埠 (通常為在生產環境中為 80,在開發環境中為 5000)。

用戶端必須能夠存取不安全的連接埠,應用程式才能接收不安全的要求,並將用戶端重新導向至安全連接埠。

如需詳細資訊,請參閱 Kestrel 端點設定ASP.NET Core 中的 HTTP.sys Web 伺服器實作

部署案例

用戶端與伺服器之間的任何防火牆也必須針對流量開啟通訊連接埠。

如果在反向 Proxy 設定中轉送要求,請在呼叫 HTTPS 重新導向中介軟體之前,先使用轉送標頭中介軟體。 轉送標頭中介軟體會使用 X-Forwarded-Proto 標頭來更新 Request.Scheme。 中介軟體允許重新導向 URI 和其他安全性原則以正常運作。 未使用轉送標頭中介軟體時,後端應用程式可能不會收到正確的配置,最後會位於重新導向迴圈中。 常見的使用者錯誤訊息是發生太多重新導向。

部署至 Azure App Service 時,請遵循教學課程:將現有的自訂 SSL 憑證繫結至 Azure Web Apps 中的指引。

選項。

下列醒目提示的程式碼會呼叫 AddHttpsRedirection 以設定中介軟體選項:

using static Microsoft.AspNetCore.Http.StatusCodes;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.AddHsts(options =>
{
    options.Preload = true;
    options.IncludeSubDomains = true;
    options.MaxAge = TimeSpan.FromDays(60);
    options.ExcludedHosts.Add("example.com");
    options.ExcludedHosts.Add("www.example.com");
});

builder.Services.AddHttpsRedirection(options =>
{
    options.RedirectStatusCode = Status307TemporaryRedirect;
    options.HttpsPort = 5001;
});

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

變更 HttpsPortRedirectStatusCode 的值時才需要呼叫 AddHttpsRedirection

上述醒目提示的程式碼:

在生產環境中設定永久重新導向

中介軟體預設會使用所有重新導向傳送 Status307TemporaryRedirect。 如果您想要在應用程式位於非開發環境中時傳送永久重新導向狀態碼,請在非開發環境的條件式檢查中包裝中介軟體選項設定。

Program.cs 中設定服務時:

using static Microsoft.AspNetCore.Http.StatusCodes;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

if (!builder.Environment.IsDevelopment())
{
    builder.Services.AddHttpsRedirection(options =>
    {
        options.RedirectStatusCode = Status308PermanentRedirect;
        options.HttpsPort = 443;
    });
}

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");

    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

HTTPS 重新導向中介軟體替代方法

使用 HTTPS 重新導向中介軟體 (UseHttpsRedirection) 的替代方法是使用 URL 重寫中介軟體 (AddRedirectToHttps)。 AddRedirectToHttps 也可以在執行重新導向時設定狀態碼和連接埠。 如需詳細資訊,請參閱 URL 重寫中介軟體

在不要求額外重新導向規則的情況下重新導向至 HTTPS 時,建議使用本主題中所述的 HTTPS 重新導向中介軟體 (UseHttpsRedirection)。

HTTP 嚴格的傳輸安全性通訊協定 (HSTS)

根據 OWASPHTTP 嚴格的傳輸安全性通訊協定 (HSTS) 是透過使用回應標頭由 Web 應用程式指定的選擇加入安全性增強功能。 支援 HSTS 的瀏覽器收到此標頭時:

  • 瀏覽器會儲存網域的設定,以防止透過 HTTP 傳送任何通訊。 瀏覽器會強制透過 HTTPS 進行所有通訊。
  • 瀏覽器可防止使用者使用不受信任或不正確憑證。 瀏覽器會停用提示,讓使用者暫時信任此類憑證。

由於 HSTS 是由用戶端強制執行,所以有一些限制:

  • 用戶端必須支援 HSTS。
  • HSTS 至少需要一個成功的 HTTPS 要求,才能建立 HSTS 原則。
  • 應用程式必須檢查每個 HTTP 要求,並重新導向或拒絕 HTTP 要求。

ASP.NET Core 會使用 UseHsts 擴充方法實作 HSTS。 下列程式碼會在應用程式不在UseHsts開發模式時呼叫

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

UseHsts 不建議用於開發環境,因為 HSTS 設定可由瀏覽器高度快取。 根據預設,UseHsts 會排除本機回送位址。

對於第一次實作 HTTPS 的生產環境,請使用其中一種 TimeSpan 方法,將初始 HstsOptions.MaxAge 設定為小型值。 將值從小時設定為不超過一天,以防您需要將 HTTPS 基礎結構還原為 HTTP。 在您確信 HTTPS 設定的持續性之後,請增加 HSTS max-age 值;常用的值為一年。

下列醒目提示的程式碼:

using static Microsoft.AspNetCore.Http.StatusCodes;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.AddHsts(options =>
{
    options.Preload = true;
    options.IncludeSubDomains = true;
    options.MaxAge = TimeSpan.FromDays(60);
    options.ExcludedHosts.Add("example.com");
    options.ExcludedHosts.Add("www.example.com");
});

builder.Services.AddHttpsRedirection(options =>
{
    options.RedirectStatusCode = Status307TemporaryRedirect;
    options.HttpsPort = 5001;
});

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();
  • 設定 Strict-Transport-Security 標頭的預先載入參數。 預先載入不是 RFC HSTS 規格的一部分,但網頁瀏覽器支援在全新安裝時預先載入 HSTS 網站。 如需詳細資訊,請參閱https://hstspreload.org/
  • 啟用 includeSubDomain,這會將 HSTS 原則套用至主機子網域。
  • Strict-Transport-Security 標頭的 max-age 參數明確設定為 60 天。 如果未設定,則預設為 30 天。 如需詳細資訊,請參閱 max-age 指示詞
  • example.com 新增至要排除的主機清單。

UseHsts 會排除下列回送主機:

  • localhost:IPv4 回送位址。
  • 127.0.0.1:IPv4 回送位址。
  • [::1]:IPv6 回送位址。

在專案建立時選擇退出 HTTPS/HSTS

在某些後端服務案例中,連線安全性是在網路的公開邊緣處理,因此不需要在每個節點上設定連線安全性。 從 Visual Studio 中的範本或 dotnet new 命令產生的 Web 應用程式會啟用 HTTPS 重新導向HSTS。 針對不需要這些案例的部署,您可以在從範本建立應用程式時選擇退出 HTTPS/HSTS。

若要選擇退出 HTTPS/HSTS:

取消核取 [針對 HTTPS 進行設定] 核取方塊。

New ASP.NET Core Web Application dialog showing the Configure for HTTPS checkbox unselected.

信任 Windows 和 macOS 上的 ASP.NET Core HTTPS 開發憑證

針對 Firefox 瀏覽器,請參閱下一節。

.NET Core SDK 包含 HTTPS 開發憑證。 憑證會安裝為初次執行體驗的一部分。 例如,dotnet --info 命令會產生下列輸出的變化:

ASP.NET Core
------------
Successfully installed the ASP.NET Core HTTPS Development Certificate.
To trust the certificate run 'dotnet dev-certs https --trust' (Windows and macOS only).
For establishing trust on other platforms refer to the platform specific documentation.
For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054.

安裝 .NET Core SDK 會將 ASP.NET Core HTTPS 開發憑證安裝至本機使用者憑證存放區。 憑證已安裝,但未受信任。 若要信任憑證,請執行一次性步驟以執行 dotnet dev-certs 工具:

dotnet dev-certs https --trust

下列命令會提供 dev-certs 工具的說明:

dotnet dev-certs https --help

警告

請勿在將要轉散發的環境中建立開發憑證,例如容器映像或虛擬機器。 這樣做可能會導致詐騙和權限提升。 為了協助避免這種情況,請先將 DOTNET_GENERATE_ASPNET_CERTIFICATE 環境變數設定為 false,然後再第一次呼叫 .NET CLI。 這會略過在 CLI 第一次執行體驗期間自動產生 ASP.NET Core 開發憑證。

使用 Firefox 信任 HTTPS 憑證以避免 SEC_ERROR_INADEQUATE_KEY_USAGE 錯誤

Firefox 瀏覽器會使用本身的憑證存放區,因此不會信任 IIS ExpressKestrel 開發人員憑證。

有兩種方法可以信任使用 Firefox 的 HTTPS 憑證;建立原則檔案,或使用 FireFox 瀏覽器進行設定。 使用瀏覽器進行設定會建立原則檔案,因此這兩種方法相當。

使用 Firefox 建立原則檔案以信任 HTTPS 憑證

在下列位置建立原則檔案 (policies.json):

將下列 JSON 新增至 Firefox 原則檔案:

{
  "policies": {
    "Certificates": {
      "ImportEnterpriseRoots": true
    }
  }
}

上述原則檔案會從 Windows 憑證存放區中的受信任憑證建立 Firefox 信任憑證。 下一節提供使用 Firefox 瀏覽器建立上述原則檔案的替代方法。

使用 Firefox 瀏覽器設定 HTTPS 憑證的信任

使用下列指示設定 security.enterprise_roots.enabled = true

  1. 在 FireFox 瀏覽器中輸入 about:config
  2. 如果您接受風險,請選取 [接受風險並繼續]
  3. 選取 [全部顯示]
  4. 設定 security.enterprise_roots.enabled = true
  5. 結束並重新啟動 Firefox

如需詳細資訊,請參閱在 Firefox 中設定憑證授權單位mozilla/policy-templates/README 檔案

如何設定適用於 Docker 的開發人員憑證

請參閱這個 GitHub 問題

信任 Linux 上的 HTTPS 憑證

建立信任是發行版本和瀏覽器特有的。 下列各節提供一些熱門發行版本與 Chromium 瀏覽器 (Edge 和 Chrome) 及 Firefox 的指示。

Ubuntu 信任服務對服務通訊的憑證

下列指示不適用於某些 Ubuntu 版本,例如 20.04。 如需詳細資訊,請參閱 GitHub 問題 dotnet/AspNetCore.Docs #23686

  1. 安裝 OpenSSL 1.1.1h 或更新版本。 如需如何更新 OpenSSL 的相關指示,請參閱您的發行版本。

  2. 執行下列命令:

    dotnet dev-certs https
    sudo -E dotnet dev-certs https -ep /usr/local/share/ca-certificates/aspnet/https.crt --format PEM
    sudo update-ca-certificates
    

上述命令會:

  • 確定已建立目前使用者的開發人員憑證。
  • 使用目前使用者的環境,匯出具有 ca-certificates 資料夾所需提升權限的憑證。
  • 移除 -E 旗標會匯出根使用者憑證,並視需要產生。 每個新產生的憑證都有不同的指紋。 以根目錄執行時,不需要 sudo-E

上述命令中的路徑是 Ubuntu 的特定路徑。 針對其他發行版本,請選取適當的路徑,或使用憑證授權單位的路徑。

使用 Edge 或 Chrome 信任 Linux 上的 HTTPS 憑證

針對 Linux 上的 Chromium 瀏覽器:

  • 為您的發行版本安裝 libnss3-tools

  • 建立或確認電腦上存在 $HOME/.pki/nssdb 資料夾。

  • 使用下列命令匯出憑證:

    dotnet dev-certs https
    sudo -E dotnet dev-certs https -ep /usr/local/share/ca-certificates/aspnet/https.crt --format PEM
    

    上述命令中的路徑是 Ubuntu 的特定路徑。 針對其他發行版本,請選取適當的路徑,或使用憑證授權單位的路徑。

  • 執行下列命令:

    certutil -d sql:$HOME/.pki/nssdb -A -t "P,," -n localhost -i /usr/local/share/ca-certificates/aspnet/https.crt
    certutil -d sql:$HOME/.pki/nssdb -A -t "C,," -n localhost -i /usr/local/share/ca-certificates/aspnet/https.crt
    
  • 結束並重新啟動瀏覽器。

在 Linux 上使用 Firefox 信任憑證

  • 使用下列命令匯出憑證:

    dotnet dev-certs https
    sudo -E dotnet dev-certs https -ep /usr/local/share/ca-certificates/aspnet/https.crt --format PEM
    

    上述命令中的路徑是 Ubuntu 的特定路徑。 針對其他發行版本,請選取適當的路徑,或使用憑證授權單位的路徑。

  • 使用下列命令在 /usr/lib/firefox/distribution/policies.json 上建立 JSON 檔案:

cat <<EOF | sudo tee /usr/lib/firefox/distribution/policies.json
{
    "policies": {
        "Certificates": {
            "Install": [
                "/usr/local/share/ca-certificates/aspnet/https.crt"
            ]
        }
    }
}
EOF

注意:Ubuntu 21.10 Firefox 隨附於貼齊套件,而安裝資料夾為 /snap/firefox/current/usr/lib/firefox

如需使用瀏覽器設定原則檔案的替代方式,請參閱本文件中的使用 Firefox 瀏覽器設定 HTTPS 憑證的信任

使用 Fedora 34 信任憑證

請參閱:

信任憑證與其他發行版本

請參閱這個 GitHub 問題

從 Windows 子系統 Linux 版信任 HTTPS 憑證

下列指示不適用於某些 Linux 發行版本,例如 Ubuntu 20.04。 如需詳細資訊,請參閱 GitHub 問題 dotnet/AspNetCore.Docs #23686

Windows 子系統 Linux 版 (WSL) 會產生 HTTPS 自我簽署開發憑證,這在 Windows 中預設不受信任。 讓 Windows 信任 WSL 憑證的最簡單方式是將 WSL 設定為使用與 Windows 相同的憑證:

  • Windows 上,將開發人員憑證匯出至檔案:

    dotnet dev-certs https -ep https.pfx -p $CREDENTIAL_PLACEHOLDER$ --trust
    

    其中 $CREDENTIAL_PLACEHOLDER$ 是密碼。

  • 在 WSL 視窗中,匯入 WSL 執行個體上的匯出憑證:

    dotnet dev-certs https --clean --import <<path-to-pfx>> --password $CREDENTIAL_PLACEHOLDER$
    

上述方法是針對每個憑證和每個 WSL 發行版本的一次性作業。 這方法比一次又一次匯出憑證更容易。 如果您在 Windows 上更新或重新產生憑證,您可能需要再次執行上述命令。

針對憑證問題進行疑難排解,例如憑證不受信任

本節提供 ASP.NET Core HTTPS 開發憑證已安裝且受信任時的說明,但您仍然有瀏覽器警告,指出憑證不受信任。 ASP.NET Core HTTPS 開發憑證是由 Kestrel 所使用的。

若要修復 IIS Express 憑證,請參閱這個 Stackoverflow 問題。

所有平台 - 憑證不受信任

執行下列命令:

dotnet dev-certs https --clean
dotnet dev-certs https --trust

關閉任何開啟的瀏覽器執行個體。 開啟新的瀏覽器視窗至應用程式。 憑證信任是由瀏覽器快取。

dotnet dev-certs https --clean Fails

上述命令可解決大部分的瀏覽器信任問題。 如果瀏覽器仍然不信任憑證,請遵循下列平台特定建議。

Docker - 憑證不受信任

  • 刪除 C:\Users{USER}\AppData\Roaming\ASP.NET\Https 資料夾。
  • 清除方案。 刪除 [bin] 和 [obj] 資料夾。
  • 重新啟動開發工具。 例如,Visual Studio 或 Visual Studio Code。

Windows - 憑證不受信任

  • 檢查憑證存放區中的憑證。 在 Current User > Personal > CertificatesCurrent User > Trusted root certification authorities > Certificates 底下都應該有具有 ASP.NET Core HTTPS development certificate 易記名稱的 localhost 憑證
  • 從個人和受信任的根憑證授權單位中移除所有找到的憑證。 請勿移除 IIS Express localhost 憑證。
  • 執行下列命令:
dotnet dev-certs https --clean
dotnet dev-certs https --trust

關閉任何開啟的瀏覽器執行個體。 開啟新的瀏覽器視窗至應用程式。

OS X - 憑證不受信任

  • 開啟 KeyChain 存取。
  • 選取 [系統金鑰鏈]。
  • 檢查 localhost 憑證是否存在。
  • 檢查其是否包含圖示上的 + 符號,表示所有使用者都信任它。
  • 從系統金鑰鏈移除憑證。
  • 執行下列命令:
dotnet dev-certs https --clean
dotnet dev-certs https --trust

關閉任何開啟的瀏覽器執行個體。 開啟新的瀏覽器視窗至應用程式。

如需針對 Visual Studio 的憑證問題進行疑難排解,請參閱使用 IIS Express 的 HTTPS 錯誤 (dotnet/AspNetCore #16892)

Linux 憑證不受信任

檢查要設定信任的憑證是否為 Kestrel 伺服器將使用的使用者 HTTPS 開發人員憑證。

在下列位置檢查目前的使用者預設 HTTPS 開發人員 Kestrel 憑證:

ls -la ~/.dotnet/corefx/cryptography/x509stores/my

HTTPS 開發人員 Kestrel 憑證檔案是 SHA1 指紋。 透過 dotnet dev-certs https --clean 刪除檔案時,系統會視需要使用不同的指紋重新產生檔案。 使用下列命令檢查匯出憑證的指紋相符:

openssl x509 -noout -fingerprint -sha1 -inform pem -in /usr/local/share/ca-certificates/aspnet/https.crt

如果憑證不相符,可能是下列其中一個情況:

  • 舊憑證。
  • 匯出根使用者的開發人員憑證。 在此情況下,請匯出憑證。

您可以在下列位置檢查根使用者憑證:

ls -la /root/.dotnet/corefx/cryptography/x509stores/my

搭配 Visual Studio 使用的 IIS Express SSL 憑證

若要修正 IIS Express 憑證的問題,請從 Visual Studio 安裝程式選取 [修復]。 如需詳細資訊,請參閱這個 GitHub 問題。

群組原則會防止自我簽署憑證受到信任

在某些情況下,群組原則可能會防止自我簽署憑證受到信任。 如需詳細資訊,請參閱這個 GitHub 問題。

其他資訊

警告

API 專案

請勿在接收敏感性資訊的 Web API 上使用 RequireHttpsAttributeRequireHttpsAttribute 會使用 HTTP 狀態碼,將瀏覽器從 HTTP 重新導向至 HTTPS。 API 用戶端可能無法了解或遵循從 HTTP 重新導向至 HTTPS。 此類用戶端可能會透過 HTTP 傳送資訊。 Web API 應該:

  • 不接聽 HTTP。
  • 關閉狀態碼為 400 (錯誤的要求) 且未提供要求的連線。

若要停用 API 中的 HTTP 重新導向,請設定 ASPNETCORE_URLS 環境變數或使用 --urls 命令列旗標。 如需詳細資訊,請參閱 Andrew Lock 的在 ASP.NET Core 中使用多個環境,以及針對 ASP.NET Core 應用程式設定 URL 的 5 種方式

HSTS 和 API 專案

預設 API 專案不包含 HSTS,因為 HSTS 通常是僅限瀏覽器的指示。 其他呼叫者,例如電話或傳統型應用程式,請勿遵循指示。 即使在瀏覽器內,透過 HTTP 對 API 的單一驗證呼叫也會對不安全的網路造成風險。 安全的方法是將 API 專案設定為只接聽並透過 HTTPS 回應。

需要 HTTPS

我們建議生產 ASP.NET Core Web 應用程式使用:

  • 用來將 HTTP 要求重新導向至 HTTPS 的 HTTPS 重新導向中介軟體 (UseHttpsRedirection)。
  • 用來將 HTTP 嚴格的傳輸安全性通訊協定 (HSTS) 標頭傳送給用戶端的 HSTS 中介軟體 (UseHsts)。

注意

部署在反向 Proxy 設定中的應用程式可讓 Proxy 處理連線安全性 (HTTPS)。 如果 Proxy 也處理 HTTPS 重新導向,則不需要使用 HTTPS 重新導向中介軟體。 如果 Proxy 伺服器也處理寫入 HSTS 標頭 (例如 IIS 10.0 (1709) 或更新版本中的原生 HSTS 支援),則應用程式不需要 HSTS 中介軟體。 如需詳細資訊,請參閱在專案建立時選擇退出 HTTPS/HSTS

UseHttpsRedirection

下列程式碼會呼叫 Startup 類別中的 UseHttpsRedirection

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

上述醒目提示的程式碼:

我們建議使用暫時重新導向,而不是永久重新導向。 連結快取可能會導致開發環境中不穩定的行為。 如果您想要在應用程式位於非開發環境中時傳送永久重新導向狀態碼,請參閱在生產環境中設定永久重新導向一節。 我們建議使用 HSTS 向用戶端發出訊號,指出只應將安全的資源要求傳送至應用程式 (僅限生產環境中)。

連接埠組態

中介軟體必須可使用連接埠,才能將不安全的要求重新導向至 HTTPS。 如果沒有可用的連接埠:

  • 不會重新導向至 HTTPS。
  • 中介軟體會記錄警告「無法判斷要重新導向的 HTTPS 連接埠。」

使用下列任何方法指定 HTTPS 連接埠:

  • 設定 HttpsRedirectionOptions.HttpsPort

  • 設定https_port主機設定

    • 在主機設定中。

    • 藉由設定 ASPNETCORE_HTTPS_PORTS 環境變數。

    • 藉由在 appsettings.json 中新增最上層項目:

      {
          "https_port": 443,
          "Logging": {
              "LogLevel": {
                  "Default": "Information",
                  "Microsoft": "Warning",
                  "Microsoft.Hosting.Lifetime": "Information"
              }
          },
          "AllowedHosts": "*"
      }
      
  • 使用 ASPNETCORE_URLS 環境變數,指出具有安全配置的連接埠。 環境變數會設定伺服器。 中介軟體會透過 IServerAddressesFeature 間接探索 HTTPS 連接埠。 此方法不適用於反向 Proxy 部署。

  • 在開發中,在 launchsettings.json 中設定 HTTPS URL。 使用 IIS Express 時啟用 HTTPS。

  • Kestrel 伺服器或 HTTP.sys 伺服器的公開邊緣部署設定 HTTPS URL 端點。 應用程式只會使用一個 HTTPS 連接埠。 中介軟體會透過 IServerAddressesFeature 探索連接埠。

注意

在反向 Proxy 設定中執行應用程式時,IServerAddressesFeature 無法使用。 使用本節所述的其中一種其他方法來設定連接埠。

邊緣部署

當 Kestrel 或 HTTP.sys 作為公開邊緣伺服器使用時,Kestrel 或 HTTP.sys 必須設定為接聽兩者:

  • 重新導向用戶端所在的安全連接埠 (通常在生產環境中為 443,在開發環境中為 5001)。
  • 不安全的連接埠 (通常為在生產環境中為 80,在開發環境中為 5000)。

用戶端必須能夠存取不安全的連接埠,應用程式才能接收不安全的要求,並將用戶端重新導向至安全連接埠。

如需詳細資訊,請參閱 Kestrel 端點設定ASP.NET Core 中的 HTTP.sys Web 伺服器實作

部署案例

用戶端與伺服器之間的任何防火牆也必須針對流量開啟通訊連接埠。

如果在反向 Proxy 設定中轉送要求,請在呼叫 HTTPS 重新導向中介軟體之前,先使用轉送標頭中介軟體。 轉送標頭中介軟體會使用 X-Forwarded-Proto 標頭來更新 Request.Scheme。 中介軟體允許重新導向 URI 和其他安全性原則以正常運作。 未使用轉送標頭中介軟體時,後端應用程式可能不會收到正確的配置,最後會位於重新導向迴圈中。 常見的使用者錯誤訊息是發生太多重新導向。

部署至 Azure App Service 時,請遵循教學課程:將現有的自訂 SSL 憑證繫結至 Azure Web Apps 中的指引。

選項。

下列醒目提示的程式碼會呼叫 AddHttpsRedirection 以設定中介軟體選項:

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();

    services.AddHsts(options =>
    {
        options.Preload = true;
        options.IncludeSubDomains = true;
        options.MaxAge = TimeSpan.FromDays(60);
        options.ExcludedHosts.Add("example.com");
        options.ExcludedHosts.Add("www.example.com");
    });

    services.AddHttpsRedirection(options =>
    {
        options.RedirectStatusCode = (int) HttpStatusCode.TemporaryRedirect;
        options.HttpsPort = 5001;
    });
}

變更 HttpsPortRedirectStatusCode 的值時才需要呼叫 AddHttpsRedirection

上述醒目提示的程式碼:

在生產環境中設定永久重新導向

中介軟體預設會使用所有重新導向傳送 Status307TemporaryRedirect。 如果您想要在應用程式位於非開發環境中時傳送永久重新導向狀態碼,請在非開發環境的條件式檢查中包裝中介軟體選項設定。

Startup.cs 中設定服務時:

public void ConfigureServices(IServiceCollection services)
{
    // IWebHostEnvironment (stored in _env) is injected into the Startup class.
    if (!_env.IsDevelopment())
    {
        services.AddHttpsRedirection(options =>
        {
            options.RedirectStatusCode = (int) HttpStatusCode.PermanentRedirect;
            options.HttpsPort = 443;
        });
    }
}

HTTPS 重新導向中介軟體替代方法

使用 HTTPS 重新導向中介軟體 (UseHttpsRedirection) 的替代方法是使用 URL 重寫中介軟體 (AddRedirectToHttps)。 AddRedirectToHttps 也可以在執行重新導向時設定狀態碼和連接埠。 如需詳細資訊,請參閱 URL 重寫中介軟體

在不要求額外重新導向規則的情況下重新導向至 HTTPS 時,建議使用本主題中所述的 HTTPS 重新導向中介軟體 (UseHttpsRedirection)。

HTTP 嚴格的傳輸安全性通訊協定 (HSTS)

根據 OWASPHTTP 嚴格的傳輸安全性通訊協定 (HSTS) 是透過使用回應標頭由 Web 應用程式指定的選擇加入安全性增強功能。 支援 HSTS 的瀏覽器收到此標頭時:

  • 瀏覽器會儲存網域的設定,以防止透過 HTTP 傳送任何通訊。 瀏覽器會強制透過 HTTPS 進行所有通訊。
  • 瀏覽器可防止使用者使用不受信任或不正確憑證。 瀏覽器會停用提示,讓使用者暫時信任此類憑證。

由於 HSTS 是由用戶端強制執行,所以有一些限制:

  • 用戶端必須支援 HSTS。
  • HSTS 至少需要一個成功的 HTTPS 要求,才能建立 HSTS 原則。
  • 應用程式必須檢查每個 HTTP 要求,並重新導向或拒絕 HTTP 要求。

ASP.NET Core 會使用 UseHsts 擴充方法實作 HSTS。 下列程式碼會在應用程式不在UseHsts開發模式時呼叫

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

UseHsts 不建議用於開發環境,因為 HSTS 設定可由瀏覽器高度快取。 根據預設,UseHsts 會排除本機回送位址。

對於第一次實作 HTTPS 的生產環境,請使用其中一種 TimeSpan 方法,將初始 HstsOptions.MaxAge 設定為小型值。 將值從小時設定為不超過一天,以防您需要將 HTTPS 基礎結構還原為 HTTP。 在您確信 HTTPS 設定的持續性之後,請增加 HSTS max-age 值;常用的值為一年。

下列程式碼範例:

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();

    services.AddHsts(options =>
    {
        options.Preload = true;
        options.IncludeSubDomains = true;
        options.MaxAge = TimeSpan.FromDays(60);
        options.ExcludedHosts.Add("example.com");
        options.ExcludedHosts.Add("www.example.com");
    });

    services.AddHttpsRedirection(options =>
    {
        options.RedirectStatusCode = (int) HttpStatusCode.TemporaryRedirect;
        options.HttpsPort = 5001;
    });
}
  • 設定 Strict-Transport-Security 標頭的預先載入參數。 預先載入不是 RFC HSTS 規格的一部分,但網頁瀏覽器支援在全新安裝時預先載入 HSTS 網站。 如需詳細資訊,請參閱https://hstspreload.org/
  • 啟用 includeSubDomain,這會將 HSTS 原則套用至主機子網域。
  • Strict-Transport-Security 標頭的 max-age 參數明確設定為 60 天。 如果未設定,則預設為 30 天。 如需詳細資訊,請參閱 max-age 指示詞
  • example.com 新增至要排除的主機清單。

UseHsts 會排除下列回送主機:

  • localhost:IPv4 回送位址。
  • 127.0.0.1:IPv4 回送位址。
  • [::1]:IPv6 回送位址。

在專案建立時選擇退出 HTTPS/HSTS

在某些後端服務案例中,連線安全性是在網路的公開邊緣處理,因此不需要在每個節點上設定連線安全性。 從 Visual Studio 中的範本或 dotnet new 命令產生的 Web 應用程式會啟用 HTTPS 重新導向HSTS。 針對不需要這些案例的部署,您可以在從範本建立應用程式時選擇退出 HTTPS/HSTS。

若要選擇退出 HTTPS/HSTS:

取消核取 [針對 HTTPS 進行設定] 核取方塊。

New ASP.NET Core Web Application dialog showing the Configure for HTTPS checkbox unselected.

信任 Windows 和 macOS 上的 ASP.NET Core HTTPS 開發憑證

針對 Firefox 瀏覽器,請參閱下一節。

.NET Core SDK 包含 HTTPS 開發憑證。 憑證會安裝為初次執行體驗的一部分。 例如,dotnet --info 命令會產生下列輸出的變化:

ASP.NET Core
------------
Successfully installed the ASP.NET Core HTTPS Development Certificate.
To trust the certificate run 'dotnet dev-certs https --trust' (Windows and macOS only).
For establishing trust on other platforms refer to the platform specific documentation.
For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054.

安裝 .NET Core SDK 會將 ASP.NET Core HTTPS 開發憑證安裝至本機使用者憑證存放區。 憑證已安裝,但未受信任。 若要信任憑證,請執行一次性步驟以執行 dotnet dev-certs 工具:

dotnet dev-certs https --trust

下列命令會提供 dev-certs 工具的說明:

dotnet dev-certs https --help

警告

請勿在將要轉散發的環境中建立開發憑證,例如容器映像或虛擬機器。 這樣做可能會導致詐騙和權限提升。 為了協助避免這種情況,請先將 DOTNET_GENERATE_ASPNET_CERTIFICATE 環境變數設定為 false,然後再第一次呼叫 .NET CLI。 這會略過在 CLI 第一次執行體驗期間自動產生 ASP.NET Core 開發憑證。

使用 Firefox 信任 HTTPS 憑證以避免 SEC_ERROR_INADEQUATE_KEY_USAGE 錯誤

Firefox 瀏覽器會使用本身的憑證存放區,因此不會信任 IIS ExpressKestrel 開發人員憑證。

有兩種方法可以信任使用 Firefox 的 HTTPS 憑證;建立原則檔案,或使用 FireFox 瀏覽器進行設定。 使用瀏覽器進行設定會建立原則檔案,因此這兩種方法相當。

使用 Firefox 建立原則檔案以信任 HTTPS 憑證

在下列位置建立原則檔案 (policies.json):

將下列 JSON 新增至 Firefox 原則檔案:

{
  "policies": {
    "Certificates": {
      "ImportEnterpriseRoots": true
    }
  }
}

上述原則檔案會從 Windows 憑證存放區中的受信任憑證建立 Firefox 信任憑證。 下一節提供使用 Firefox 瀏覽器建立上述原則檔案的替代方法。

使用 Firefox 瀏覽器設定 HTTPS 憑證的信任

使用下列指示設定 security.enterprise_roots.enabled = true

  1. 在 FireFox 瀏覽器中輸入 about:config
  2. 如果您接受風險,請選取 [接受風險並繼續]
  3. 選取 [全部顯示]
  4. 設定 security.enterprise_roots.enabled = true
  5. 結束並重新啟動 Firefox

如需詳細資訊,請參閱在 Firefox 中設定憑證授權單位mozilla/policy-templates/README 檔案

如何設定適用於 Docker 的開發人員憑證

請參閱這個 GitHub 問題

信任 Linux 上的 HTTPS 憑證

建立信任是發行版本和瀏覽器特有的。 下列各節提供一些熱門發行版本與 Chromium 瀏覽器 (Edge 和 Chrome) 及 Firefox 的指示。

Ubuntu 信任服務對服務通訊的憑證

  1. 安裝 OpenSSL 1.1.1h 或更新版本。 如需如何更新 OpenSSL 的相關指示,請參閱您的發行版本。

  2. 執行下列命令:

    dotnet dev-certs https
    sudo -E dotnet dev-certs https -ep /usr/local/share/ca-certificates/aspnet/https.crt --format PEM
    sudo update-ca-certificates
    

上述命令會:

  • 確定已建立目前使用者的開發人員憑證。
  • 使用目前使用者的環境,匯出具有 ca-certificates 資料夾所需提升權限的憑證。
  • 移除 -E 旗標會匯出根使用者憑證,並視需要產生。 每個新產生的憑證都有不同的指紋。 以根目錄執行時,不需要 sudo-E

上述命令中的路徑是 Ubuntu 的特定路徑。 針對其他發行版本,請選取適當的路徑,或使用憑證授權單位的路徑。

使用 Edge 或 Chrome 信任 Linux 上的 HTTPS 憑證

針對 Linux 上的 Chromium 瀏覽器:

  • 為您的發行版本安裝 libnss3-tools

  • 建立或確認電腦上存在 $HOME/.pki/nssdb 資料夾。

  • 使用下列命令匯出憑證:

    dotnet dev-certs https
    sudo -E dotnet dev-certs https -ep /usr/local/share/ca-certificates/aspnet/https.crt --format PEM
    

    上述命令中的路徑是 Ubuntu 的特定路徑。 針對其他發行版本,請選取適當的路徑,或使用憑證授權單位的路徑。

  • 執行下列命令:

    certutil -d sql:$HOME/.pki/nssdb -A -t "P,," -n localhost -i /usr/local/share/ca-certificates/aspnet/https.crt
    certutil -d sql:$HOME/.pki/nssdb -A -t "C,," -n localhost -i /usr/local/share/ca-certificates/aspnet/https.crt
    
  • 結束並重新啟動瀏覽器。

在 Linux 上使用 Firefox 信任憑證

  • 使用下列命令匯出憑證:

    dotnet dev-certs https
    sudo -E dotnet dev-certs https -ep /usr/local/share/ca-certificates/aspnet/https.crt --format PEM
    

    上述命令中的路徑是 Ubuntu 的特定路徑。 針對其他發行版本,請選取適當的路徑,或使用憑證授權單位的路徑。

  • 使用下列內容在 /usr/lib/firefox/distribution/policies.json 上建立 JSON 檔案:

cat <<EOF | sudo tee /usr/lib/firefox/distribution/policies.json
{
    "policies": {
        "Certificates": {
            "Install": [
                "/usr/local/share/ca-certificates/aspnet/https.crt"
            ]
        }
    }
}
EOF

如需使用瀏覽器設定原則檔案的替代方式,請參閱本文件中的使用 Firefox 瀏覽器設定 HTTPS 憑證的信任

使用 Fedora 34 信任憑證

Fedora 上的 Firefox

echo 'pref("general.config.filename", "firefox.cfg");
pref("general.config.obscure_value", 0);' > ./autoconfig.js

echo '//Enable policies.json
lockPref("browser.policies.perUserDir", false);' > firefox.cfg

echo "{
    \"policies\": {
        \"Certificates\": {
            \"Install\": [
                \"aspnetcore-localhost-https.crt\"
            ]
        }
    }
}" > policies.json

dotnet dev-certs https -ep localhost.crt --format PEM

sudo mv autoconfig.js /usr/lib64/firefox/
sudo mv firefox.cfg /usr/lib64/firefox/
sudo mv policies.json /usr/lib64/firefox/distribution/
mkdir -p ~/.mozilla/certificates
cp localhost.crt ~/.mozilla/certificates/aspnetcore-localhost-https.crt
rm localhost.crt

信任 Fedora 上的 dotnet 對 dotnet

sudo cp localhost.crt /etc/pki/tls/certs/localhost.pem
sudo update-ca-trust
rm localhost.crt

如需詳細資訊,請參閱這個 GitHub 註解

信任憑證與其他發行版本

請參閱這個 GitHub 問題

從 Windows 子系統 Linux 版信任 HTTPS 憑證

Windows 子系統 Linux 版 (WSL) 會產生 HTTPS 自我簽署開發憑證。 若要將 Windows 憑證存放區設定為信任 WSL 憑證:

  • 將開發人員憑證匯出至 Windows 上的檔案:

    dotnet dev-certs https -ep C:\<<path-to-folder>>\aspnetcore.pfx -p $CREDENTIAL_PLACEHOLDER$
    

    其中 $CREDENTIAL_PLACEHOLDER$ 是密碼。

  • 在 WSL 視窗中,匯入 WSL 執行個體上的匯出憑證:

    dotnet dev-certs https --clean --import /mnt/c/<<path-to-folder>>/aspnetcore.pfx -p $CREDENTIAL_PLACEHOLDER$
    

上述方法是針對每個憑證和每個 WSL 發行版本的一次性作業。 這方法比一次又一次匯出憑證更容易。 如果您在 Windows 上更新或重新產生憑證,您可能需要再次執行上述命令。

針對憑證問題進行疑難排解,例如憑證不受信任

本節提供 ASP.NET Core HTTPS 開發憑證已安裝且受信任時的說明,但您仍然有瀏覽器警告,指出憑證不受信任。 ASP.NET Core HTTPS 開發憑證是由 Kestrel 所使用的。

若要修復 IIS Express 憑證,請參閱這個 Stackoverflow 問題。

所有平台 - 憑證不受信任

執行下列命令:

dotnet dev-certs https --clean
dotnet dev-certs https --trust

關閉任何開啟的瀏覽器執行個體。 開啟新的瀏覽器視窗至應用程式。 憑證信任是由瀏覽器快取。

dotnet dev-certs https --clean Fails

上述命令可解決大部分的瀏覽器信任問題。 如果瀏覽器仍然不信任憑證,請遵循下列平台特定建議。

Docker - 憑證不受信任

  • 刪除 C:\Users{USER}\AppData\Roaming\ASP.NET\Https 資料夾。
  • 清除方案。 刪除 [bin] 和 [obj] 資料夾。
  • 重新啟動開發工具。 例如,Visual Studio、Visual Studio Code 或 Visual Studio for Mac。

Windows - 憑證不受信任

  • 檢查憑證存放區中的憑證。 在 Current User > Personal > CertificatesCurrent User > Trusted root certification authorities > Certificates 底下都應該有具有 ASP.NET Core HTTPS development certificate 易記名稱的 localhost 憑證
  • 從個人和受信任的根憑證授權單位中移除所有找到的憑證。 請勿移除 IIS Express localhost 憑證。
  • 執行下列命令:
dotnet dev-certs https --clean
dotnet dev-certs https --trust

關閉任何開啟的瀏覽器執行個體。 開啟新的瀏覽器視窗至應用程式。

OS X - 憑證不受信任

  • 開啟 KeyChain 存取。
  • 選取 [系統金鑰鏈]。
  • 檢查 localhost 憑證是否存在。
  • 檢查其是否包含圖示上的 + 符號,表示所有使用者都信任它。
  • 從系統金鑰鏈移除憑證。
  • 執行下列命令:
dotnet dev-certs https --clean
dotnet dev-certs https --trust

關閉任何開啟的瀏覽器執行個體。 開啟新的瀏覽器視窗至應用程式。

如需針對 Visual Studio 的憑證問題進行疑難排解,請參閱使用 IIS Express 的 HTTPS 錯誤 (dotnet/AspNetCore #16892)

Linux 憑證不受信任

檢查要設定信任的憑證是否為 Kestrel 伺服器將使用的使用者 HTTPS 開發人員憑證。

在下列位置檢查目前的使用者預設 HTTPS 開發人員 Kestrel 憑證:

ls -la ~/.dotnet/corefx/cryptography/x509stores/my

HTTPS 開發人員 Kestrel 憑證檔案是 SHA1 指紋。 透過 dotnet dev-certs https --clean 刪除檔案時,系統會視需要使用不同的指紋重新產生檔案。 使用下列命令檢查匯出憑證的指紋相符:

openssl x509 -noout -fingerprint -sha1 -inform pem -in /usr/local/share/ca-certificates/aspnet/https.crt

如果憑證不相符,可能是下列其中一個情況:

  • 舊憑證。
  • 匯出根使用者的開發人員憑證。 在此情況下,請匯出憑證。

您可以在下列位置檢查根使用者憑證:

ls -la /root/.dotnet/corefx/cryptography/x509stores/my

搭配 Visual Studio 使用的 IIS Express SSL 憑證

若要修正 IIS Express 憑證的問題,請從 Visual Studio 安裝程式選取 [修復]。 如需詳細資訊,請參閱這個 GitHub 問題。

其他資訊