共用方式為


在 ASP.NET Core 中設定 Windows 驗證

作者:Rick AndersonKirk Larkin

Windows 驗證 (也稱為 Negotiate、Kerberos 或 NTLM 驗證) 可以針對使用 IISKestrelHTTP.sys 裝載的 ASP.NET Core 應用程式進行設定。

Windows 驗證依賴作業系統以驗證 ASP.NET Core 應用程式的使用者。 Windows 驗證用於使用 Active Directory 網域身分識別或 Windows 帳戶在公司網路上執行的伺服器,以識別使用者。 Windows 驗證最適合使用者、用戶端應用程式和網頁伺服器屬於相同 Windows 網域的內部網路環境。

何時使用 Windows 驗證

Windows 驗證適用於在組織私人內部網路內運作的 Web 應用程式,只有同一網路內的員工 (和其他授權使用者) 才能存取。 使用者管理是在 Active Directory (AD) 內完成,使用者使用其現有的 Windows 網域帳戶進行驗證。

Windows 驗證為內部網路應用程式提供數個優點:

  • 順暢的使用者體驗 - 系統會根據使用者的作用中 Windows 工作階段自動驗證使用者,或透過標準瀏覽器對話方塊提示輸入其 Windows 認證。
  • 與 Active Directory 整合 - 利用現有的 Windows 基礎結構和安全策略,包括使用者群組、帳戶鎖定和多重要素驗證 (MFA)。
  • 安全認證處理 - 驗證是透過 Kerberos 等安全通訊協定來處理,不需要管理個別的使用者認證。
  • 角色型授權 - 應用程式可以從 Active Directory 存取使用者和群組資訊,在應用程式內啟用角色型存取控制 (RBAC)。
  • 減少管理額外負荷 - 無需維護單獨的使用者資料庫或憑證管理系統。

這使得 Windows 身份驗證非常適合想要使用其現有 Windows 基礎結構(例如 Intranet 門戶)的組織。

Note

HTTP/2 不支援 Windows 驗證。 雖然可以透過HTTP/2回應傳送驗證挑戰,但用戶端必須降級至HTTP/1.1才能完成驗證程式。 這是通訊協定限制,而不是取代 Windows 驗證。 一旦通過身份驗證,正常的 HTTP/2 通訊就可以恢復以進行後續請求。

針對公開的應用程式,不建議使用Windows 驗證,因為安全性和可用性考量。 這些原因包括:

  • Windows 身份驗證最好保留在內部以保護 Active Directory,將其暴露在內部網絡之外會引入安全風險。
  • 外部使用者沒有 Windows 網域帳戶。
  • 安全地配置必要的網路基礎設施很複雜,防火牆或代理可能會幹擾身份驗證過程。
  • 它不是跨平台的,也不提供設計和用戶體驗的自定義選項。

不同案例的替代方案

根據您的應用程式需求,請考慮下列替代方案:

針對面向公眾的應用程式:

對於同時具有內部網路和外部使用者的混合環境

  • Active Directory 同盟服務 (ADFS) 搭配 OpenID Connect
  • 具有混合式設定的 Azure Active Directory

對於使用新式驗證的企業環境:

  • 具有單一登入的 Azure Active Directory
  • 使用第三方身分識別提供商的 SAML 型解決方案

Proxy 和負載平衡器案例

Windows 驗證是一種具狀態案例,主要用於內部網路,其中 Proxy 或負載平衡器通常不會處理用戶端與伺服器之間的流量。 如果使用了 Proxy 或負載平衡器,則 Windows 驗證只有在 Proxy 或負載平衡器時才有效:

  • 處理驗證。
  • 將使用者驗證資訊傳遞至應用程式 (例如,在要求標頭中),以處理驗證資訊。

在使用 Proxy 和負載平衡器的環境中,Windows 驗證的替代方案是 Active Directory 同盟服務 (ADFS) 搭配 OpenID Connect (OIDC)。

IIS/IIS Express

在 中Microsoft.AspNetCore.Authentication.Negotiate呼叫 AddAuthentication和驗證服務:

using Microsoft.AspNetCore.Authentication.Negotiate;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
   .AddNegotiate();

builder.Services.AddAuthorization(options =>
{
    options.FallbackPolicy = options.DefaultPolicy;
});
builder.Services.AddRazorPages();

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

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

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapRazorPages();

app.Run();

上述程式碼是由已指定 Razor的 ASP.NET Core Pages 範本所產生。

啟動設定 (偵錯工具)

啟動設定的組態只會影響 IIS Express 的 Properties/launchSettings.json 檔案,而不會設定 Windows 驗證的 IIS。 IIS 一節中會說明伺服器設定。

您可以設定透過 Visual Studio 或 .NET CLI 取得的 Web 應用程式範本,以支援可自動更新 Properties/launchSettings.json 檔案的 Windows 驗證。

新項目

建立新的 Razor Pages 或 MVC 應用程式。 在 [其他資訊] 對話方塊中,將 [驗證類型] 設定為 [Windows]

執行應用程式。 使用者名稱會出現在轉譯應用程式的使用者介面中。

現有專案

專案的屬性會啟用 Windows 驗證並停用匿名驗證。 開啟 [啟動設定檔] 對話方塊:

  1. 在 [方案總管] 中,以滑鼠右鍵按一下專案,然後選取 [屬性]
  2. 選取 [偵錯] > [一般] 索引標籤,然後選取 [開啟偵錯啟動設定檔 UI]
  3. 清除 [啟用匿名驗證] 的核取方塊。
  4. 選取 [啟用 Windows 驗證] 的核取方塊。

或者,您可以在 iisSettings 檔案的 launchSettings.json 節點中設定屬性:

"iisSettings": {
    "windowsAuthentication": true,
    "anonymousAuthentication": false,
    "iisExpress": {
        "applicationUrl": "http://localhost:52171/",
        "sslPort": 44308
    }
}

IIS

IIS 會使用 ASP.NET Core 模組來裝載 ASP.NET Core 應用程式。 Windows 驗證是透過 web.config 檔案針對 IIS 設定的。 下列各節說明如何:

  • 提供本機 web.config 檔案,以在部署應用程式時啟用伺服器上的 Windows 驗證。
  • 使用 IIS 管理員來設定已部署至伺服器之 ASP.NET Core 應用程式的 web.config 檔案。

如果您尚未這麼做,請啟用 IIS 以裝載 ASP.NET Core 應用程式。 如需詳細資訊,請參閱在使用 IIS 的 Windows 上裝載 ASP.NET Core

啟用 Windows 驗證的 IIS 角色服務。 如需詳細資訊,請參閱在 IIS 角色服務中啟用 Windows 驗證 (請參閱步驟 2)

IIS 整合中介軟體預設會設定為自動驗證要求。 如需詳細資訊,請參閱在使用 IIS 的 Windows 上裝載 ASP.NET Core:IIS 選項 (AutomaticAuthentication)

ASP.NET Core 模組預設會設定為將 Windows 驗證權杖轉送至應用程式。 如需詳細資訊,請參閱 ASP.NET Core 模組組態參考:aspNetCore 元素的屬性

使用下列其中一個方法:

  • 發佈和部署專案之前,請將下列 web.config 檔案新增至專案根目錄:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <location path="." inheritInChildApplications="false">
        <system.webServer>
          <security>
            <authentication>
              <anonymousAuthentication enabled="false" />
              <windowsAuthentication enabled="true" />
            </authentication>
          </security>
        </system.webServer>
      </location>
    </configuration>
    

    當使用 .NET SDK 發佈專案時(在項目檔中未將 <IsTransformWebConfigDisabled> 屬性設定為 true),發佈的 web.config 檔案會包含 <location><system.webServer><security><authentication> 段落。 如需屬性的詳細資訊<IsTransformWebConfigDisabled>,請參閱 web.config 檔案

  • 發佈和部署專案之後,請使用 IIS 管理員執行伺服器端設定:

    1. 在 [IIS 管理員] 中,選取 [連線] 側邊欄中 [網站] 節點 底下的 IIS 網站。
    2. 按兩下 IIS 區域中的 [驗證]
    3. 選取 [匿名驗證]。 在 [動作] 側邊欄中選取 [停用]
    4. 選取 [Windows 驗證] 。 在 [動作] 側邊欄中選取 [啟用]

    當採取這些動作時,IIS 管理員會修改應用程式的 web.config 檔案。 系統會使用 <system.webServer><security><authentication>anonymousAuthentication 的更新設定來新增 windowsAuthentication 節點:

    <system.webServer>
      <security>
        <authentication>
          <anonymousAuthentication enabled="false" />
          <windowsAuthentication enabled="true" />
        </authentication>
      </security>
    </system.webServer>
    

    <system.webServer> IIS 管理員新增至 web.config 檔案的區段不在 .NET SDK 發佈應用程式時所新增的應用程式<location>區段之外。 由於 區段是在 <location> 節點外部新增,因此任何子應用程式都會繼承設定至目前的應用程式。 若要防止繼承,請將新增的 <security> 區段移到 .NET SDK 提供的 <location><system.webServer> 區段之內。

    當 IIS 管理員用來新增 IIS 設定時,它只會影響伺服器上應用程式的 web.config 檔案。 如果伺服器的 web.config 複本由專案的 web.config 檔案取代,則應用程式的後續部署可能會覆寫伺服器上的設定。 使用下列其中一種方法來管理設定:

    • 使用 IIS 管理員在部署時覆寫檔案之後,重設 web.config 檔案中的設定。
    • 使用設定在本機將 web.config 檔案新增至應用程式。

Kestrel

Microsoft.AspNetCore.Authentication.Negotiate NuGet 套件可以與Kestrel一起使用,在 Windows、Linux 和 macOS 上透過協商和 Kerberos 來啟用 Windows 驗證。

Warning

認證可以在連線上跨要求保存。 除非 Proxy 使用 Kestrel 維護 1:1 連接親和性 (持續連線),否則交涉驗證不得與 Proxy 搭配使用。

Note

交涉處理常式會偵測基礎伺服器是否原生支援 Windows 驗證,以及是否啟用它。 如果伺服器支援 Windows 驗證但已停用,則會擲回錯誤,並要求您啟用伺服器實作。 在伺服器中啟用 Windows 驗證時,交涉處理常式會以透明方式將驗證要求轉送給伺服器。

驗證和備援授權政策由下列醒目的程式碼 Program.cs 啟用:

using Microsoft.AspNetCore.Authentication.Negotiate;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
   .AddNegotiate();

builder.Services.AddAuthorization(options =>
{
    options.FallbackPolicy = options.DefaultPolicy;
});
builder.Services.AddRazorPages();

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

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

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapRazorPages();

app.Run();

上述程式碼是由已指定 Razor的 ASP.NET Core Pages 範本所產生。

已標示的線條:

Note

呼叫 AddAuthenticationAddNegotiate 會註冊並設定交涉處理程序,但不會執行每個請求的驗證。 鑑別中介軟體(UseAuthentication)會調用處理常式並填入HttpContext.User,而且必須在UseAuthorization之前,以便原則評估能夠運作。

Kerberos 驗證和角色型存取控制 (RBAC)

Linux 或 macOS 上的 Kerberos 驗證不會為已驗證的使用者提供任何角色資訊。 若要將角色和群組資訊新增至 Kerberos 使用者,驗證處理常式必須設定為從 LDAP 網域擷取角色。 最基本的設定只會指定要查詢的 LDAP 網域,並使用已驗證的使用者內容來查詢 LDAP 網域:

using Microsoft.AspNetCore.Authentication.Negotiate;
using System.Runtime.InteropServices;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
    .AddNegotiate(options =>
    {
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
        {
            options.EnableLdap("contoso.com");
        }
    });

某些設定可能需要特定認證才能查詢 LDAP 網域。 您可以在下列醒目提示的選項中指定認證:

using Microsoft.AspNetCore.Authentication.Negotiate;
using System.Runtime.InteropServices;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
        .AddNegotiate(options =>
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                options.EnableLdap(settings =>
                {
                    settings.Domain = "contoso.com";
                    settings.MachineAccountName = "machineName";
                    settings.MachineAccountPassword =
                                      builder.Configuration["Password"];
                });
            }
        });

builder.Services.AddRazorPages();

交涉驗證處理常式預設會解析巢狀網域。 在大型或複雜的 LDAP 環境中,解析巢狀網域可能會導致查閱緩慢或每個使用者使用大量記憶體。 您可以使用 IgnoreNestedGroups 選項來停用巢狀網域解析。

允許匿名要求。 使用 ASP.NET Core授權 來挑戰匿名要求以進行驗證。

Windows 環境設定

Microsoft.AspNetCore.Authentication.Negotiate API 會執行使用者模式驗證。 服務主體名稱 (SPN) 必須新增至執行服務的使用者帳戶,而不是電腦帳戶。 在系統管理命令殼層中執行 setspn -S HTTP/myservername.mydomain.com myuser

Kerberos 與 NTLM

Kestrel 上適用於 ASP.NET Core 的交涉套件會嘗試使用 Kerberos,這是比 NTLM 更安全且更具效能的驗證配置:

using Microsoft.AspNetCore.Authentication.Negotiate;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
   .AddNegotiate();

builder.Services.AddAuthorization(options =>
{
    options.FallbackPolicy = options.DefaultPolicy;
});
builder.Services.AddRazorPages();

var app = builder.Build();

NegotiateDefaults.AuthenticationScheme 會指定 Kerberos,因為它是預設值。

IIS、IISExpress 及 Kestrel 同時支援 Kerberos 和 NTLM

使用 IIS 或 IISExpress 搭配 Fiddler 之類的工具檢查 WWW-Authenticate: 標頭會顯示 Negotiate 或 NTLM。

Kestrel 僅會顯示 WWW-Authenticate: Negotiate

WWW-Authenticate: Negotiate 標頭表示伺服器可以使用 NTLM 或 Kerberos。 Kestrel 需要 Negotiate 標頭前置詞,其不支援直接在要求或回應驗證標頭中指定 NTLM。 Kestrel 中支援 NTLM,但必須以 Negotiate 的形式傳送。

在 Kestrel 上,若要查看是否使用 NTLM 或 Kerberos,Base64 會將標頭解碼,其會顯示 NTLMHTTPHTTP 表示已使用 Kerberos。

Linux 和 macOS 環境設定

如需將 Linux 或 macOS 電腦加入 Windows 網域的指示,請參閱使用 Windows 驗證 - Kerberos 將 Azure Data Studio 連線至 SQL Server 一文。 指示會在網域上建立 Linux 電腦的電腦帳戶。 SPN 必須新增至該電腦帳戶。

Note

遵循使用 Windows 驗證 - Kerberos 將 Azure Data Studio 連線至 SQL Server 一文中的指導時,請視需要將 python-software-properties 取代為 python3-software-properties

一旦 Linux 或 macOS 電腦加入網域,需要額外的步驟才能提供具有 SPN 的 keytab 檔案

  • 在網域控制站上,將新的 Web 服務 SPN 新增至電腦帳戶:
    • setspn -S HTTP/mywebservice.mydomain.com mymachine
    • setspn -S HTTP/mywebservice@MYDOMAIN.COM mymachine
  • 使用 ktpass 來產生 keytab 檔案:
    • ktpass -princ HTTP/mywebservice.mydomain.com@MYDOMAIN.COM -pass myKeyTabFilePassword -mapuser MYDOMAIN\mymachine$ -pType KRB5_NT_PRINCIPAL -out c:\temp\mymachine.HTTP.keytab -crypto AES256-SHA1
    • 某些欄位必須依照指示以大寫指定。
  • 將 keytab 檔案複製到 Linux 或 macOS 電腦。
  • 透過環境變數選取 keytab 檔案:export KRB5_KTNAME=/tmp/mymachine.HTTP.keytab
  • 叫用 klist 以顯示目前可供使用的 SPN。

Note

keytab 檔案包含網域存取認證,且必須據以保護。

HTTP.sys

HTTP.sys 支援使用 Negotiate、NTLM 或基本驗證的核心模式 Windows 驗證。

下列程式碼會新增驗證,並將應用程式的 Web 主機設定為搭配 Windows 驗證使用 HTTP.sys:

using Microsoft.AspNetCore.Server.HttpSys;
using System.Runtime.InteropServices;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAuthentication(HttpSysDefaults.AuthenticationScheme);

if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
    builder.WebHost.UseHttpSys(options =>
        {
            options.Authentication.Schemes =
                AuthenticationSchemes.NTLM |
                AuthenticationSchemes.Negotiate;
            options.Authentication.AllowAnonymous = false;
        });
}

Note

HTTP.sys 會使用 Kerberos 驗證通訊協定委派給核心模式驗證。 Kerberos 和 HTTP.sys 不支援使用者模式驗證。 必須使用電腦帳戶來解密 Kerberos 權杖/票證,該權杖/票證取自 Active Directory,並由用戶端將其轉送至伺服器來驗證使用者。 請註冊主機的服務主體名稱 (SPN),而非應用程式的使用者。

Note

Nano Server 1709 版或更新版本不支援 HTTP.sys。 若要將 Windows 驗證和 HTTP.sys 搭配用於 Nano Server,請使用 Server Core (microsoft/windowsservercore) 容器 (請參閱 https://hub.docker.com/_/microsoft-windows-servercore)。 如需伺服器核心的詳細資訊,請參閱什麼是 Windows Server 中的伺服器核心安裝選項?

授權使用者

匿名存取的設定狀態會決定在應用程式中使用 [Authorize][AllowAnonymous] 屬性的方式。 下列兩節說明如何處理不允許和允許的匿名存取設定狀態。

不允許匿名存取

啟用 Windows 驗證並停用匿名存取時,[Authorize][AllowAnonymous] 屬性不會有任何作用。 如果 IIS 網站設定為不允許匿名存取,則要求永遠不會到達應用程式。 因此,[AllowAnonymous] 屬性不適用。

允許匿名存取

同時啟用 Windows 驗證和匿名存取時,請使用 [Authorize][AllowAnonymous] 屬性。 [Authorize] 屬性可讓您保護需要驗證之應用程式的端點。 [AllowAnonymous] 屬性會覆寫應用程式中允許匿名存取的 [Authorize] 屬性。 如需屬性使用方式的詳細資料,請參閱 ASP.NET Core 中的簡單授權

Note

根據預設,缺少存取頁面授權的使用者會看到空的 HTTP 403 回應。 StatusCodePages 中介軟體可以設定為提供使用者更好的「拒絕存取」體驗。

Impersonation

ASP.NET Core 不會實作模擬。 應用程式在針對所有要求時,以應用程式的識別執行,並使用應用程式集區或處理程序的身分識別。 如果應用程式需要代表使用者執行動作,請在 WindowsIdentity.RunImpersonatedRunImpersonatedAsync中使用 Program.cs。 在此內容中執行單一動作,然後關閉內容。

app.Run(async (context) =>
{
    try
    {
        var user = (WindowsIdentity)context.User.Identity!;

        await context.Response
            .WriteAsync($"User: {user.Name}\tState: {user.ImpersonationLevel}\n");

        await WindowsIdentity.RunImpersonatedAsync(user.AccessToken, async () =>
        {
            var impersonatedUser = WindowsIdentity.GetCurrent();
            var message =
                $"User: {impersonatedUser.Name}\t" +
                $"State: {impersonatedUser.ImpersonationLevel}";

            var bytes = Encoding.UTF8.GetBytes(message);
            await context.Response.Body.WriteAsync(bytes, 0, bytes.Length);
        });
    }
    catch (Exception e)
    {
        await context.Response.WriteAsync(e.ToString());
    }
});

Microsoft.AspNetCore.Authentication.Negotiate雖然套件在 Windows、Linux 和 macOS 上啟用驗證,但 Windows 僅支持模擬。

索賠轉換

使用 IIS 裝載時,不會內部呼叫 AuthenticateAsync 來將使用者初始化。 因此,預設會在未啟動每個驗證之後,使用 IClaimsTransformation 實作來轉換宣告。 如需詳細資訊和啟用宣告轉換的程式碼範例,請參閱內含式與跨處理程序裝載之間的差異

其他資源

Windows 驗證 (也稱為 Negotiate、Kerberos 或 NTLM 驗證) 可以針對使用 IISKestrelHTTP.sys 裝載的 ASP.NET Core 應用程式進行設定。

Windows 驗證依賴作業系統以驗證 ASP.NET Core 應用程式的使用者。 當您的伺服器使用 Active Directory 網域身分識別或 Windows 帳戶在公司網路上執行時,您可以使用 Windows 驗證來識別使用者。 Windows 驗證最適合使用者、用戶端應用程式和網頁伺服器屬於相同 Windows 網域的內部網路環境。

何時使用 Windows 驗證

Windows 驗證適用於在組織私人內部網路內運作的 Web 應用程式,只有同一網路內的員工 (和其他授權使用者) 才能存取。 使用者管理是在 Active Directory (AD) 內完成,使用者使用其現有的 Windows 網域帳戶進行驗證。

Windows 驗證為內部網路應用程式提供數個優點:

  • 順暢的使用者體驗 - 系統會根據使用者的作用中 Windows 工作階段自動驗證使用者,或透過標準瀏覽器對話方塊提示輸入其 Windows 認證。
  • 與 Active Directory 整合 - 利用現有的 Windows 基礎結構和安全策略,包括使用者群組、帳戶鎖定和多重要素驗證 (MFA)。
  • 安全認證處理 - 驗證是透過 Kerberos 等安全通訊協定來處理,不需要管理個別的使用者認證。
  • 角色型授權 - 應用程式可以從 Active Directory 存取使用者和群組資訊,在應用程式內啟用角色型存取控制 (RBAC)。
  • 減少管理額外負荷 - 無需維護單獨的使用者資料庫或憑證管理系統。

這使得 Windows 身份驗證非常適合想要使用其現有 Windows 基礎結構(例如 Intranet 門戶)的組織。

Note

HTTP/2 不支援 Windows 驗證。 雖然可以透過HTTP/2回應傳送驗證挑戰,但用戶端必須降級至HTTP/1.1才能完成驗證程式。 這是通訊協定限制,而不是取代 Windows 驗證。 一旦通過身份驗證,正常的 HTTP/2 通訊就可以恢復以進行後續請求。

針對公開的應用程式,不建議使用Windows 驗證,因為安全性和可用性考量。 這些原因包括:

  • Windows 身份驗證最好保留在內部以保護 Active Directory,將其暴露在內部網絡之外會引入安全風險。
  • 外部使用者沒有 Windows 網域帳戶。
  • 安全地配置必要的網路基礎設施很複雜,防火牆或代理可能會幹擾身份驗證過程。
  • 它不是跨平台的,也不提供設計和用戶體驗的自定義選項。

不同案例的替代方案

根據您的應用程式需求,請考慮下列替代方案:

針對面向公眾的應用程式:

對於同時具有內部網路和外部使用者的混合環境

  • Active Directory 同盟服務 (ADFS) 搭配 OpenID Connect
  • 具有混合式設定的 Azure Active Directory

對於使用新式驗證的企業環境:

  • 具有單一登入的 Azure Active Directory
  • 使用第三方身分識別提供商的 SAML 型解決方案

Proxy 和負載平衡器案例

Windows 驗證是一種具狀態案例,主要用於內部網路,其中 Proxy 或負載平衡器通常不會處理用戶端與伺服器之間的流量。 如果使用了 Proxy 或負載平衡器,則 Windows 驗證只有在 Proxy 或負載平衡器時才有效:

  • 處理驗證。
  • 將使用者驗證資訊傳遞至應用程式 (例如,在要求標頭中),以處理驗證資訊。

在使用 Proxy 和負載平衡器的環境中,Windows 驗證的替代方案是 Active Directory 同盟服務 (ADFS) 搭配 OpenID Connect (OIDC)。

IIS/IIS Express

AddAuthentication 中叫用 Microsoft.AspNetCore.Server.IISIntegration (Startup.ConfigureServices 命名空間) 以新增驗證服務:

services.AddAuthentication(IISDefaults.AuthenticationScheme);

啟動設定 (偵錯工具)

啟動設定的組態只會影響 IIS Express 的 Properties/launchSettings.json 檔案,而不會設定 Windows 驗證的 IIS。 IIS 一節中會說明伺服器設定。

您可以設定可透過 Visual Studio 或 .NET CLI 取得的 Web 應用程式範本,以支援可自動更新 Properties/launchSettings.json 檔案的 Windows 驗證。

新項目

  1. 建立新專案。
  2. 選取 [ASP.NET Core Web 應用程式]。 選取 下一步
  3. 在 [專案名稱] 欄位中提供名稱。 確認 [位置] 項目正確或提供專案的位置。 選取 ,創建
  4. 選取 [驗證] 底下的 [變更]
  5. 在 [變更驗證] 視窗中,選取 [Windows 驗證]。 請選擇 [確定]
  6. 選取 [Web 應用程式]
  7. 選取 ,創建

執行應用程式。 使用者名稱會出現在轉譯應用程式的使用者介面中。

現有專案

專案的屬性會啟用 Windows 驗證並停用匿名驗證:

  1. 以滑鼠右鍵按一下 [方案總管] 中的專案,然後選取 [屬性]
  2. 選取 [偵錯] 索引標籤。
  3. 清除 [啟用匿名驗證] 的核取方塊。
  4. 選取 [啟用 Windows 驗證] 的核取方塊。
  5. 儲存並關閉屬性頁。

或者,您可以在 iisSettings 檔案的 launchSettings.json 節點中設定屬性:

"iisSettings": {
    "windowsAuthentication": true,
    "anonymousAuthentication": false,
    "iisExpress": {
        "applicationUrl": "http://localhost:52171/",
        "sslPort": 44308
    }
}

修改現有的專案時,請確認項目檔包含中繼套件Microsoft.AspNetCore.App的套件參考。

IIS

IIS 會使用 ASP.NET Core 模組來裝載 ASP.NET Core 應用程式。 Windows 驗證是透過 web.config 檔案針對 IIS 設定的。 下列各節說明如何:

  • 提供本機 web.config 檔案,以在部署應用程式時啟用伺服器上的 Windows 驗證。
  • 使用 IIS 管理員來設定已部署至伺服器之 ASP.NET Core 應用程式的 web.config 檔案。

如果您尚未這麼做,請啟用 IIS 以裝載 ASP.NET Core 應用程式。 如需詳細資訊,請參閱在使用 IIS 的 Windows 上裝載 ASP.NET Core

啟用 Windows 驗證的 IIS 角色服務。 如需詳細資訊,請參閱在 IIS 角色服務中啟用 Windows 驗證 (請參閱步驟 2)

IIS 整合中介軟體預設會設定為自動驗證要求。 如需詳細資訊,請參閱在使用 IIS 的 Windows 上裝載 ASP.NET Core:IIS 選項 (AutomaticAuthentication)

ASP.NET Core 模組預設會設定為將 Windows 驗證權杖轉送至應用程式。 如需詳細資訊,請參閱 ASP.NET Core 模組組態參考:aspNetCore 元素的屬性

使用下列其中一個方法:

  • 發佈和部署專案之前,請將下列 web.config 檔案新增至專案根目錄:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <location path="." inheritInChildApplications="false">
        <system.webServer>
          <security>
            <authentication>
              <anonymousAuthentication enabled="false" />
              <windowsAuthentication enabled="true" />
            </authentication>
          </security>
        </system.webServer>
      </location>
    </configuration>
    

    當使用 .NET SDK 發佈專案時(在項目檔中未將 <IsTransformWebConfigDisabled> 屬性設定為 true),發佈的 web.config 檔案會包含 <location><system.webServer><security><authentication> 段落。 如需 <IsTransformWebConfigDisabled> 屬性的詳細資訊,請參閱在使用 IIS 的 Windows 上裝載 ASP.NET Core

  • 發佈和部署專案之後,請使用 IIS 管理員執行伺服器端設定:

    1. 在 [IIS 管理員] 中,選取 [連線] 側邊欄中 [網站] 節點 底下的 IIS 網站。
    2. 按兩下 IIS 區域中的 [驗證]
    3. 選取 [匿名驗證]。 在 [動作] 側邊欄中選取 [停用]
    4. 選取 [Windows 驗證] 。 在 [動作] 側邊欄中選取 [啟用]

    當採取這些動作時,IIS 管理員會修改應用程式的 web.config 檔案。 系統會使用 <system.webServer><security><authentication>anonymousAuthentication 的更新設定來新增 windowsAuthentication 節點:

    <system.webServer>
      <security>
        <authentication>
          <anonymousAuthentication enabled="false" />
          <windowsAuthentication enabled="true" />
        </authentication>
      </security>
    </system.webServer>
    

    <system.webServer> IIS 管理員新增至 web.config 檔案的區段不在 .NET SDK 發佈應用程式時所新增的應用程式<location>區段之外。 由於 區段是在 <location> 節點外部新增,因此任何子應用程式都會繼承設定至目前的應用程式。 若要防止繼承,請將新增的 <security> 區段移到 .NET SDK 提供的 <location><system.webServer> 區段之內。

    當 IIS 管理員用來新增 IIS 設定時,它只會影響伺服器上應用程式的 web.config 檔案。 如果伺服器的 web.config 複本由專案的 web.config 檔案取代,則應用程式的後續部署可能會覆寫伺服器上的設定。 使用下列其中一種方法來管理設定:

    • 使用 IIS 管理員在部署時覆寫檔案之後,重設 web.config 檔案中的設定。
    • 使用設定在本機將 web.config 檔案新增至應用程式。

Kestrel

Microsoft.AspNetCore.Authentication.Negotiate NuGet 套件可用於Kestrel在 Windows、Linux 和 macOS 上使用 Negotiate 和 Kerberos 來支援 Windows 驗證。

Warning

認證可以在連線上跨要求保存。 除非 Proxy 使用 Kestrel 維護 1:1 連接親和性 (持續連線),否則交涉驗證不得與 Proxy 搭配使用。

Note

交涉處理常式會偵測基礎伺服器是否原生支援 Windows 驗證,以及是否啟用它。 如果伺服器支援 Windows 驗證但已停用,則會擲回錯誤,並要求您啟用伺服器實作。 在伺服器中啟用 Windows 驗證時,交涉處理常式會以透明方式將驗證要求轉送給伺服器。

AddAuthentication 中叫用 AddNegotiateStartup.ConfigureServices 以新增驗證服務:

// using Microsoft.AspNetCore.Authentication.Negotiate;
// using Microsoft.Extensions.DependencyInjection;

services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
   .AddNegotiate();

UseAuthentication 中呼叫 Startup.Configure 以新增驗證中介軟體:

app.UseAuthentication();

如需中介軟體的詳細資訊,請參閱 ASP.NET Core 中介軟體

Kerberos 驗證和角色型存取控制 (RBAC)

Linux 或 macOS 上的 Kerberos 驗證不會為已驗證的使用者提供任何角色資訊。 若要將角色和群組資訊新增至 Kerberos 使用者,驗證處理常式必須設定為從 LDAP 網域擷取角色。 最基本的設定只會指定要查詢的 LDAP 網域,並使用已驗證的使用者內容來查詢 LDAP 網域:

services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
    .AddNegotiate(options =>
    {
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
        {
            options.EnableLdap("contoso.com");
        }
    });

某些設定可能需要特定認證才能查詢 LDAP 網域。 您可以在下列醒目提示的選項中指定認證:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
    services.AddDatabaseDeveloperPageExceptionFilter();
    services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
        .AddEntityFrameworkStores<ApplicationDbContext>();

    services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
        .AddNegotiate(options =>
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                options.EnableLdap(settings =>
                {
                    settings.Domain = "contoso.com";
                    settings.MachineAccountName = "machineName";
                    settings.MachineAccountPassword = Configuration["Password"]
                });
            }
        });

    services.AddRazorPages();
}

交涉驗證處理常式預設會解析巢狀網域。 在大型或複雜的 LDAP 環境中,解析巢狀網域可能會導致查閱緩慢或每個使用者使用大量記憶體。 您可以使用 IgnoreNestedGroups 選項來停用巢狀網域解析。

允許匿名要求。 使用 ASP.NET Core授權 來挑戰匿名要求以進行驗證。

AuthenticationScheme需要Microsoft.AspNetCore.Authentication.Negotiate NuGet 套件

Windows 環境設定

Microsoft.AspNetCore.Authentication.Negotiate API 會執行使用者模式驗證。 服務主體名稱 (SPN) 必須新增至執行服務的使用者帳戶,而不是電腦帳戶。 在系統管理命令殼層中執行 setspn -S HTTP/myservername.mydomain.com myuser

Linux 和 macOS 環境設定

如需將 Linux 或 macOS 電腦加入 Windows 網域的指示,請參閱使用 Windows 驗證 - Kerberos 將 Azure Data Studio 連線至 SQL Server 一文。 指示會在網域上建立 Linux 電腦的電腦帳戶。 SPN 必須新增至該電腦帳戶。

Note

遵循使用 Windows 驗證 - Kerberos 將 Azure Data Studio 連線至 SQL Server 一文中的指導時,請視需要將 python-software-properties 取代為 python3-software-properties

一旦 Linux 或 macOS 電腦加入網域,需要額外的步驟才能提供具有 SPN 的 keytab 檔案

  • 在網域控制站上,將新的 Web 服務 SPN 新增至電腦帳戶:
    • setspn -S HTTP/mywebservice.mydomain.com mymachine
    • setspn -S HTTP/mywebservice@MYDOMAIN.COM mymachine
  • 使用 ktpass 來產生 keytab 檔案:
    • ktpass -princ HTTP/mywebservice.mydomain.com@MYDOMAIN.COM -pass myKeyTabFilePassword -mapuser MYDOMAIN\mymachine$ -pType KRB5_NT_PRINCIPAL -out c:\temp\mymachine.HTTP.keytab -crypto AES256-SHA1
    • 某些欄位必須依照指示以大寫指定。
  • 將 keytab 檔案複製到 Linux 或 macOS 電腦。
  • 透過環境變數選取 keytab 檔案:export KRB5_KTNAME=/tmp/mymachine.HTTP.keytab
  • 叫用 klist 以顯示目前可供使用的 SPN。

Note

keytab 檔案包含網域存取認證,且必須據以保護。

HTTP.sys

HTTP.sys 支援使用 Negotiate、NTLM 或基本驗證的核心模式 Windows 驗證。

AddAuthentication 中叫用 Microsoft.AspNetCore.Server.HttpSys (Startup.ConfigureServices 命名空間) 以新增驗證服務:

services.AddAuthentication(HttpSysDefaults.AuthenticationScheme);

將應用程式的 Web 主機設定為使用 HTTP.sys 搭配 Windows 驗證 (Program.cs)。 UseHttpSys 位於 Microsoft.AspNetCore.Server.HttpSys 命名空間中。

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>()
                    .UseHttpSys(options =>
                    {
                        options.Authentication.Schemes = 
                            AuthenticationSchemes.NTLM | 
                            AuthenticationSchemes.Negotiate;
                        options.Authentication.AllowAnonymous = false;
                    });
            });
}

Note

HTTP.sys 會使用 Kerberos 驗證通訊協定委派給核心模式驗證。 Kerberos 和 HTTP.sys 不支援使用者模式驗證。 必須使用電腦帳戶來解密 Kerberos 權杖/票證,該權杖/票證取自 Active Directory,並由用戶端將其轉送至伺服器來驗證使用者。 請註冊主機的服務主體名稱 (SPN),而非應用程式的使用者。

Note

Nano Server 1709 版或更新版本不支援 HTTP.sys。 若要將 Windows 驗證和 HTTP.sys 搭配用於 Nano Server,請使用 Server Core (microsoft/windowsservercore) 容器 (請參閱 https://hub.docker.com/_/microsoft-windows-servercore)。 如需伺服器核心的詳細資訊,請參閱什麼是 Windows Server 中的伺服器核心安裝選項?

授權使用者

匿名存取的設定狀態會決定在應用程式中使用 [Authorize][AllowAnonymous] 屬性的方式。 下列兩節說明如何處理不允許和允許的匿名存取設定狀態。

不允許匿名存取

啟用 Windows 驗證並停用匿名存取時,[Authorize][AllowAnonymous] 屬性不會有任何作用。 如果 IIS 網站設定為不允許匿名存取,則要求永遠不會到達應用程式。 因此,[AllowAnonymous] 屬性不適用。

允許匿名存取

同時啟用 Windows 驗證和匿名存取時,請使用 [Authorize][AllowAnonymous] 屬性。 [Authorize] 屬性可讓您保護需要驗證之應用程式的端點。 [AllowAnonymous] 屬性會覆寫應用程式中允許匿名存取的 [Authorize] 屬性。 如需屬性使用方式的詳細資料,請參閱 ASP.NET Core 中的簡單授權

Note

根據預設,缺少存取頁面授權的使用者會看到空的 HTTP 403 回應。 StatusCodePages 中介軟體可以設定為提供使用者更好的「拒絕存取」體驗。

Impersonation

ASP.NET Core 不會實作模擬。 應用程式在針對所有要求時,以應用程式的識別執行,並使用應用程式集區或處理程序的身分識別。 如果應用程式應該代表使用者執行動作,請在 RunImpersonatedAsync中使用 Windows.RunImpersonatedStartup.Configure。 在此內容中執行單一動作,然後關閉內容。

app.Run(async (context) =>
{
    try
    {
        var user = (WindowsIdentity)context.User.Identity;

        await context.Response
            .WriteAsync($"User: {user.Name}\tState: {user.ImpersonationLevel}\n");

        WindowsIdentity.RunImpersonated(user.AccessToken, () =>
        {
            var impersonatedUser = WindowsIdentity.GetCurrent();
            var message =
                $"User: {impersonatedUser.Name}\t" +
                $"State: {impersonatedUser.ImpersonationLevel}";

            var bytes = Encoding.UTF8.GetBytes(message);
            context.Response.Body.Write(bytes, 0, bytes.Length);
        });
    }
    catch (Exception e)
    {
        await context.Response.WriteAsync(e.ToString());
    }
});

Microsoft.AspNetCore.Authentication.Negotiate雖然套件在 Windows、Linux 和 macOS 上啟用驗證,但 Windows 僅支持模擬。

索賠轉換

使用 IIS 裝載時,不會內部呼叫 AuthenticateAsync 來將使用者初始化。 因此,預設會在未啟動每個驗證之後,使用 IClaimsTransformation 實作來轉換宣告。 如需詳細資訊和啟用宣告轉換的程式碼範例,請參閱內含式與跨處理程序裝載之間的差異

其他資源