共用方式為


將 ASP.NET 架構驗證移轉至 ASP.NET 核心

身份驗證是 Web 應用程式的關鍵元件,負責處理跨 HTTP 請求的使用者身分驗證。 從 ASP.NET Framework 移轉至 ASP.NET Core 時,驗證會帶來獨特的挑戰,因為這兩個架構處理驗證的方式非常不同。

如需有關 ASP.NET Core 中驗證的一般資訊,請參閱 ASP.NET Core 驗證概觀。 如需授權的相關資訊,請參閱 ASP.NET Core 中的授權簡介

為什麼驗證移轉很複雜

ASP.NET Framework 和 ASP.NET Core 的驗證方法根本不同:

  • ASP.NET Framework 提供內建驗證模組,具有自動設定功能,並與 System.Web 緊密整合
  • ASP.NET Core 使用基於中間件的方法,具有明確的配置和依賴注入

這些差異表示您無法在不進行變更的情況下,簡單地將驗證碼從 Framework 移至 Core。

驗證類型和移轉挑戰

不同的驗證類型呈現不同程度的移轉複雜度:

  • ASP.NET 框架:使用 Microsoft.Owincookie 身份驗證中間件
  • ASP.NET 核心:使用 CookieAuthentication 不同配置的中間件
  • 移轉挑戰: Cookie 格式、加密金鑰和設定差異

JWT 持有者代幣

  • ASP.NET 架構:通常透過自訂模組或 OWIN 中介軟體來處理
  • ASP.NET Core:透過原生支援 Microsoft.AspNetCore.Authentication.JwtBearer
  • 遷移挑戰:令牌驗證參數差異和中間件註冊

Windows 驗證

  • ASP.NET Framework:內建 IIS 整合
  • ASP.NET 核心:需要明確配置,可能需要託管模型變更
  • 移轉挑戰:伺服器設定和驗證流程差異

表單驗證

  • ASP.NET 框架: 內建System.Web.Security.FormsAuthentication
  • ASP.NET Core:沒有直接對等的,需要遷移到 cookie 身份驗證
  • 遷移挑戰:需要重寫完整的身份驗證系統

自訂驗證

  • ASP.NET 框架:實作自訂模組 IHttpModule
  • ASP.NET 核心:自訂中介軟體或驗證處理常式
  • 遷移挑戰:從模組到中間件的完整架構變更

移轉策略概觀

在移轉期間,您有三種主要方法來處理驗證:

  1. 完全重寫 - 重寫所有驗證碼以使用 ASP.NET Core 的原生驗證
  2. 遠端驗證 - 使用 System.Web 配接器將驗證委派給 ASP.NET Framework 應用程式
  3. 共用 cookie 驗證 - 在架構和核心應用程式之間共用驗證 Cookie (適用於 OWIN 型案例)

對於大多數應用程式,移轉至原生 ASP.NET Core 驗證可提供最佳效能和可維護性。 不過,較大的應用程式或具有複雜驗證需求的應用程式可能會受益於使用 System.Web 配接器的累加方法。

選擇移轉方法

您有三個主要選項可將驗證從 ASP.NET Framework 移轉至 ASP.NET Core。 您的選擇取決於您的驗證類型、移轉時間表、您是否需要同時執行兩個應用程式,以及您願意重寫的程式碼量。

快速決策指南

回答以下問題以選擇您的方法:

  1. 您是否正在進行完全重寫或增量遷移?

  2. 您的 ASP.NET Framework 應用程式使用哪種類型的驗證?

    • OWIN cookie 驗證→繼續問題 3
    • 表單驗證、JWT 持有人權杖、Windows 驗證或自訂驗證→ 遠端驗證
  3. 您的 ASP.NET Framework 和 ASP.NET Core 應用程式是否需要存取相同的驗證狀態?

  4. 您可以在兩個應用程式之間配置相符的資料保護設定嗎?

移轉方法比較

方法 程式碼變更 績效 身份驗證共享 使用時機
完全重寫 高 - 重寫所有身份驗證碼 最佳 沒有 完整重寫、效能至關重要的應用程式、非 OWIN 驗證
遠端驗證 低 - 保留現有模式 普通 完整 累加式移轉、複雜驗證、Windows 驗證
共享 cookie 中等 - 更新設定 完整 OWIN cookie 驗證、效能關鍵共用驗證 (請參閱替代方案)

完全重寫為 ASP.NET 核心驗證

當您執行完整的移轉、具有非 OWIN 驗證或想要最佳效能和可維護性時,請選擇此方法。

ASP.NET Core 提供全面的身份驗證支持,具有高性能和廣泛的自定義選項。 這種方法需要重寫身份驗證代碼,但從長遠來看提供了最大的好處。

完整重寫的優點和缺點

優點 缺點
最佳效能和安全性 需要重寫所有驗證碼
原生 ASP.NET Core 實作 沒有自動移轉路徑
完全控制驗證流程 新驗證模式的學習曲線
沒有額外的相依性 從框架模式進行重大變更
存取最新的 ASP.NET Core 驗證功能 移轉期間的潛在停機時間

移轉考慮

移轉至原生 ASP.NET 核心驗證時:

根據您的架構驗證類型進行選擇:

需要更改代碼:

  • 取代 HttpContext.User 存取模式 (大部分相容)
  • Program.cs 更新驗證中介軟體的註冊
  • 將自訂驗證邏輯移轉至 ASP.NET 核心模式
  • 更新授權屬性和原則

何時選擇此方法:

  • 您有能力重構與身份驗證相關的程式碼
  • 性能是重中之重
  • 您不會與舊版應用程式共用驗證狀態
  • 您想要完全消除 System.Web 相依性
  • 您的架構應用程式會使用表單驗證、自訂模組或 JWT 權杖

遠程驗證

備註

這會利用 System.Web 配接器 來簡化移轉。

當您需要在累加式移轉期間在 ASP.NET Framework 和 ASP.NET Core 應用程式之間共用驗證時,或當您有難以移轉的複雜驗證時,請選擇此方法。

System.Web 配接器的遠端驗證功能可讓 ASP.NET Core 應用程式延遲至 ASP.NET 應用程式來判斷使用者的身分識別。 這可以在維護單一身份驗證系統的同時逐步遷移。

遠端驗證的運作方式

  1. 當 ASP.NET Core 應用程式處理要求時,如果遠端應用程式驗證是預設結構描述,或由要求的端點指定,則 RemoteAuthenticationAuthHandler 會嘗試驗證使用者。
  2. 處理程序會向 ASP.NET 應用程式的驗證端點發出 HTTP 請求,並從目前的請求中轉發已設定的標頭(預設為 AuthorizationCookie 標頭)。
  3. ASP.NET 應用程式會處理驗證,並傳回序列化 ClaimsPrincipal 或 HTTP 狀態碼,指出失敗。
  4. ASP.NET Core 應用程式會使用結果來建立使用者的身分識別或處理驗證挑戰。

遠端身份驗證的優點和缺點

優點 缺點
只需最少的程式碼變更 額外的 HTTP 請求負荷
適用於任何框架身份驗證類型 應用程式之間的網路相依性
逐步遷移能力 更複雜的偵錯
保留現有的驗證邏輯 需要兩個應用程式都執行
處理複雜的身份驗證場景 有限的 Windows 驗證支援

何時選擇遠端驗證

在下列情況下選擇遠端驗證:

  • 您的 ASP.NET 應用程式未使用 Microsoft.Owincookie 驗證
  • 您需要一個可與各種身份驗證機制配合使用的靈活解決方案
  • 您需要逐步將身份驗證邏輯遷移到 ASP.NET Core
  • 您有難以重寫的複雜自訂驗證
  • 您正在進行累加移轉,且需要共用驗證狀態

遠端驗證設定

在已根據 [使用者入門] 設定的解決方案中啟用遠端驗證,只需要一些小的程式碼變更。

首先,請遵循 [遠端應用程式設定] 指示來連線 ASP.NET Core 和 ASP.NET 應用程式。 然後,只需要呼叫幾個額外的擴充方法,即可啟用遠端應用程式驗證。

ASP.NET 應用程式設定

ASP.NET 應用程式必須設定為新增驗證端點。 藉由呼叫 AddAuthenticationServer 擴充方法來設定 HTTP 模組來監看驗證端點的要求,以新增驗證端點。 請注意,遠端驗證案例通常也想要新增 Proxy 支援,讓任何與驗證相關的重新導向正確地路由至 ASP.NET Core 應用程式,而不是 ASP.NET。

HttpApplicationHost.RegisterHost(builder =>
{
    builder.AddSystemWebAdapters()
        .AddProxySupport(options => options.UseForwardedHeaders = true)
        .AddRemoteAppServer(options =>
        {
            options.ApiKey = ConfigurationManager.AppSettings["RemoteAppApiKey"];
        })
        .AddAuthenticationServer();
});

ASP.NET Core 應用程式設定

接下來,ASP.NET Core 應用程式必須設定為啟用驗證處理常式,以對 ASP.NET 應用程式提出 HTTP 要求來驗證使用者。 同樣地,註冊 System.Web 配接器服務時呼叫 AddAuthenticationClient 即可完成:

builder.Services.AddSystemWebAdapters()
    .AddRemoteAppClient(options =>
    {
        options.RemoteAppUrl = new Uri(builder.Configuration
            ["ReverseProxy:Clusters:fallbackCluster:Destinations:fallbackApp:Address"]);
        options.ApiKey = builder.Configuration["RemoteAppApiKey"];
    })
    .AddAuthenticationClient(true);

傳遞至呼叫的 AddAuthenticationClient 布林值會指定遠端應用程式驗證是否應該是預設驗證結構描述。 傳遞 true 會導致使用者透過所有要求的遠端應用程式驗證進行驗證,而傳遞 false 表示只有在特別要求遠端應用程式結構描述時,使用者才會使用遠端應用程式驗證進行驗證 (例如,使用控制器上或動作方法上的 [Authorize(AuthenticationSchemes = RemoteAppAuthenticationDefaults.AuthenticationScheme)])。 針對此參數傳遞 false 的優點是只會對原始 ASP.NET 應用程式提出 HTTP 要求,以為需要遠端應用程式驗證的端點進行驗證,但缺點是需要批註所有這類端點,以指出它們將使用遠端應用程式驗證。

使用 Aspire時,配置將通過環境變量完成,並由 AppHost 設置。 若要啟用遠端工作階段,必須啟用選項:

...

var coreApp = builder.AddProject<Projects.AuthRemoteIdentityCore>("core")
    .WithHttpHealthCheck()
    .WaitFor(frameworkApp)
    .WithIncrementalMigrationFallback(frameworkApp, options => options.RemoteAuthentication = RemoteAuthentication.DefaultScheme);

...

完成此操作後,它將自動掛接在框架和核心應用程式中。

使用 YARP 備援的遠端認證

使用具有基於 YARP 的回退機制之 ASP.NET Framework 應用程式進行遠端驗證時,請確保回退請求不會觸發遠端驗證。 如果遠端認證在備援期間執行,應用程式會對 Framework 應用程式進行不必要的額外呼叫,可能導致混淆行為。

為避免對備援請求執行遠端驗證,請採用以下其中一種方法:

  • 在 YARP 備援路由中使用路由短路元資料,使路由繞過中介軟體管線的其他部分。 例如,呼叫 ShortCircuit 備援端點,如遠端應用程式設定指引所示,以及 在路由後的短路中介軟體中呼叫。
  • 不要把遠端驗證當作預設的驗證方案。 相反地,只為需要遠端驗證的端點設定。 例如,將false傳遞給AddAuthenticationClient,並在這些端點上明確指定遠端認證方案。

將遠端驗證與特定端點搭配使用

當您將預設配置設為 false時,您可以指定特定控制器或動作的遠端驗證:

[Authorize(AuthenticationSchemes = RemoteAppAuthenticationDefaults.AuthenticationScheme)]
public class SecureController : Controller
{
    // This controller uses remote authentication
    public IActionResult Index()
    {
        return View();
    }
}

// Or on specific actions
public class HomeController : Controller
{
    [Authorize(AuthenticationSchemes = RemoteAppAuthenticationDefaults.AuthenticationScheme)]
    public IActionResult SecureAction()
    {
        return View();
    }
}

實作自訂驗證結果處理器

您可以實作自訂處理器,在使用驗證結果之前修改它們:

public class CustomAuthResultProcessor : IRemoteAuthenticationResultProcessor
{
    public Task ProcessAsync(RemoteAuthenticationResult result, HttpContext context)
    {
        // Custom logic to process authentication results
        if (result.Headers.ContainsKey("Location"))
        {
            // Modify redirect URLs or other logic
        }
        
        return Task.CompletedTask;
    }
}

// Register the custom processor
builder.Services.AddScoped<IRemoteAuthenticationResultProcessor, CustomAuthResultProcessor>();

最後,如果 ASP.NET Core 應用程式先前未包含驗證中介軟體,則需要啟用該中介軟體 (在路由中介軟體之後,但在授權中介軟體之前)。 如需中介軟體排序的詳細資訊,請參閱 ASP.NET 核心中介軟體

app.UseAuthentication();

安全性考慮

實作遠端身份驗證時,請考慮以下安全面向:

  • API 金鑰安全性:用於 ASP.NET Core 和 ASP.NET 應用程式之間通訊的 API 金鑰應使用 配置提供者 安全地存儲,而不是硬編碼。
  • 網路安全:應用程式之間的通訊應透過生產環境中的安全通道 (HTTPS) 進行。
  • 標頭轉發:請謹慎轉發哪些標頭,以避免暴露敏感資訊。 僅轉發身份驗證所需的標頭。
  • 端點保護:ASP.NET 應用程式上的驗證端點應該只能由 ASP.NET Core 應用程式存取,而外部用戶端則無法存取。

故障排除

設定遠端驗證時的常見問題:

  • 驗證失敗:驗證兩個應用程式之間的 API 金鑰是否相符,以及驗證端點路徑是否已正確設定。
  • 重新導向迴圈:確保已 RedirectUrlProcessor 正確設定為重新導向至 ASP.NET Core 應用程式,而不是 ASP.NET 應用程式。
  • 遺漏宣告:確認 ASP.NET 應用程式已正確序列化, ClaimsPrincipal 且已包含所有必要的宣告。

設計

  1. 當 ASP.NET Core 應用程式處理要求時,如果遠端應用程式驗證是預設結構描述,或由要求的端點指定,則 RemoteAuthenticationAuthHandler 會嘗試驗證使用者。
    1. 處理常式會向 ASP.NET 應用程式的驗證端點提出 HTTP 要求。 它會將設定的標頭從目前的要求複製到這個新的標頭,以便轉送與驗證相關的資料。 如上所述,預設行為是複製 AuthorizationCookie 標頭。 此外,也會新增 API 金鑰標頭以達到安全性目的。
  2. ASP.NET 應用程式會為傳送至驗證端點的要求提供服務。 只要 API 金鑰相符,ASP.NET 應用程式就會傳回目前使用者的 ClaimsPrincipal 序列化至回應本文,否則會傳回 HTTP 狀態碼 (例如 401 或 302),以及指出失敗的回應標頭。
  3. 當 ASP.NET Core 應用程式的 RemoteAuthenticationAuthHandler 收到來自 ASP.NET 應用程式的回應時:
    1. 如果成功返回 ClaimsPrincipal,驗證處理元件將會將其反序列化,並將它用作當前使用者的身分識別。
    2. 如果 ClaimsPrincipal 未成功傳回,處理常式將會儲存結果,如果驗證受到挑戰 (例如,因為使用者正在存取受保護的資源),要求的回應將會以狀態碼,以及從驗證端點的回應中選取的回應標頭進行更新。 這可讓挑戰回應 (例如重新導向至登入頁面) 傳播給終端使用者。
      1. 由於來自 ASP.NET 應用程式驗證端點的結果可能包含該端點的特定資料,因此使用者可以向 ASP.NET Core 應用程式註冊 IRemoteAuthenticationResultProcessor 實作,這些實作會在使用之前於任何驗證結果上執行。 例如,一個內建 IRemoteAuthenticationResultProcessorRedirectUrlProcessor,它會尋找 Location 個從驗證端點傳回的回應標頭,並確保它們會重新導向回 ASP.NET Core 應用程式的主機,而不是直接到 ASP.NET 應用程式。

已知的限制

此遠端驗證方法有一些已知的限制:

  1. Windows 驗證:由於 Windows 驗證相依於 Windows 身分識別的控制碼,因此此功能不支援 Windows 驗證。 已計劃未來工作來探索共用 Windows 驗證的運作方式。 如需詳細資訊,請參閱 dotnet/systemweb-adapters#246。 針對 Windows 驗證案例,請考慮改用 ASP.NET Core 應用程式中的 [在 ASP.NET Core 中設定 Windows 驗證 ]。
  2. 使用者管理動作:此功能允許 ASP.NET Core 應用程式使用由 ASP.NET 應用程式驗證的身分,但與使用者相關的所有動作(登入、登出等)仍需要透過 ASP.NET 應用程式路由。
  3. 效能考量:每個驗證請求都需要對 ASP.NET 應用程式進行 HTTP 呼叫,這可能會影響效能。 如果效能至關重要,請考慮使用共用 cookie 驗證 (在替代方案一節中所述)。

如果 ASP.NET 應用程式中的驗證是使用驗證中介軟體完成 Microsoft.OwinCookie 的,則遠端驗證的替代解決方案是設定 ASP.NET 和 ASP.NET 核心應用程式,以便它們能夠共用驗證 cookie。

共享 Cookie 的運作方式

共用驗證 cookie 可啟用:

  • 這兩個應用程式都會從相同的 cookie判斷使用者身分識別。
  • 登入或登出某個應用程式會將使用者登入或登出另一個應用程式。

這兩個應用程式都配置為:

  • 使用相同的 cookie 名稱和網域設定
  • 共用資料保護金鑰以用於cookie加密/解密
  • 使用相容的 cookie 驗證中介軟體

這允許在一個應用程式中驗證的使用者在提出請求時在另一個應用程式中自動驗證。

優點 缺點
共享驗證最佳效能 僅適用於 OWIN cookie 驗證
沒有額外的 HTTP 請求 需要匹配的數據保護設置
這兩個應用程式都可以處理登入/登出 更複雜的初始配置
無縫的使用者體驗 僅限於基於cookie的身份驗證
降低網路額外負荷 需要協調部署

共用 Cookie 的驗證限制

請注意,因為登入通常取決於特定資料庫,並非所有驗證功能都能在這兩個應用程式中運作:

  • 使用者應該只透過其中一個應用程式登入,無論是 ASP.NET 或 ASP.NET Core 應用程式,只要資料庫設定為使用即可。
  • 這兩個應用程式都可以看到使用者的身分識別和宣告。
  • 這兩個應用程式都能夠將使用者登出。

有關如何在 ASP.NET 與 ASP.NET Core 應用程式之間設定共用驗證 Cookie 的詳細資料,請參閱 cookie 共用文件。 如需有關 ASP.NET Core 中驗證的cookie詳細資訊,請參閱在沒有 ASP.NET Core cookie的情況下使用Identity驗證。 關於在 Framework 與 Core 應用程式間共享受保護值時的設定 <machineKey> 與資料保護指引,請參見 ASP.NET machineKey to ASP.NET Core 遷移

System.Web 介面卡 GitHub 存放庫中的下列範例示範具有共用cookie設定的遠端應用程式驗證,可讓這兩個應用程式讓使用者登入和登出:

在下列情況下選擇共用 Cookie 驗證:

  • 您的 ASP.NET 應用程式已使用 Microsoft.Owincookie 驗證
  • 您可以在兩個應用程式之間配置相符的資料保護設定
  • 效能至關重要,而且您想要將 HTTP 要求降到最低
  • 您希望這兩個應用程式都能處理使用者登入/登出作業
  • 您可以自如地管理共用加密金鑰

如果下列兩者都成立,則共用驗證是不錯的選擇:

  • ASP.NET 應用程式已經在使用 Microsoft.Owincookie 驗證。
  • 您可以使用相符的資料保護設定來更新 ASP.NET 應用程式和 ASP.NET Core 應用程式。 比對共用資料保護設定包括共用檔案路徑、Redis 快取或 Azure Blob 儲存體來儲存資料保護金鑰。 如需更多資訊,請參閱 ASP.NET Core Data Protection Overview

針對其他案例,本文件先前所述的遠端驗證方法更有彈性,而且可能更適合。

另請參閱