在 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 網域的內部網路環境。

注意

HTTP/2 不支援 Windows 驗證。 驗證挑戰可以在 HTTP/2 回應上傳送,但用戶端必須在驗證之前降級為 HTTP/1.1。

Proxy 和負載平衡器案例

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

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

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

IIS/IIS Express

Program.cs 中呼叫 AddAuthentication,以新增 NuGet 套件 Microsoft.AspNetCore.Authentication.Negotiate 和驗證服務:

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();

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

啟動設定 (偵錯工具)

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

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

新增專案

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

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

現有專案

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

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

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

"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 Core 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 檔案。 系統會使用 anonymousAuthenticationwindowsAuthentication 的更新設定來新增 <system.webServer><security><authentication> 節點:

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

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

    當 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 驗證。

警告

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

注意

交涉處理常式會偵測基礎伺服器是否原生支援 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();

上述程式碼是由已指定 Windows 驗證的 ASP.NET Core Razor Pages 範本所產生。 上述程式碼中會使用下列 API:

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 元件會執行使用者模式驗證。 服務主體名稱 (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 必須新增至該電腦帳戶。

注意

遵循使用 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。

注意

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;
        });
}

注意

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

注意

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

授權使用者

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

不允許匿名存取

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

允許匿名存取

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

注意

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

模擬

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

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 網域的內部網路環境。

注意

HTTP/2 不支援 Windows 驗證。 驗證挑戰可以在 HTTP/2 回應上傳送,但用戶端必須在驗證之前降級為 HTTP/1.1。

Proxy 和負載平衡器案例

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

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

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

IIS/IIS Express

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

services.AddAuthentication(IISDefaults.AuthenticationScheme);

啟動設定 (偵錯工具)

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

您可以設定可透過 Visual Studio 或 .NET Core 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. 儲存並關閉屬性頁。

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

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

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

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 Core 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 檔案。 系統會使用 anonymousAuthenticationwindowsAuthentication 的更新設定來新增 <system.webServer><security><authentication> 節點:

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

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

    當 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 驗證。

警告

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

注意

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

Startup.ConfigureServices 中叫用 AddAuthenticationAddNegotiate 以新增驗證服務:

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

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

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

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 需要 NuGet 套件 Microsoft.AspNetCore.Authentication.Negotiate

Windows 環境設定

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

Linux 和 macOS 環境設定

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

注意

遵循使用 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。

注意

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

HTTP.sys

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

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

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;
                    });
            });
}

注意

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

注意

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

授權使用者

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

不允許匿名存取

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

允許匿名存取

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

注意

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

模擬

ASP.NET Core 不會實作模擬。 應用程式會針對所有要求,使用應用程式集區或處理程序身分識別,以應用程式身分識別來執行。 如果應用程式應該代表使用者執行動作,請在 Startup.Configure終端機內嵌中介軟體中使用 WindowsIdentity.RunImpersonatedRunImpersonatedAsync。 在此內容中執行單一動作,然後關閉內容。

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 實作來轉換宣告。 如需詳細資訊和啟用宣告轉換的程式碼範例,請參閱內含式與跨處理程序裝載之間的差異

其他資源