リモート認証

System.Web アダプターのリモート認証機能を使用すると、ASP.NET Core アプリは、ASP.NET アプリに遅延することで、ユーザーの ID を判断 (HTTP 要求を認証) できます。 この機能を有効にすると、エンドポイントに対して行われた要求に対して認証されたユーザーを表すシリアル化された ClaimsPrincipal を返すエンドポイントが ASP.NET アプリに追加されます。 ASP.NET Core アプリは、(リモート認証が有効になっているエンドポイントの場合) ASP.NET アプリでそのエンドポイントを呼び出し、ASP.NET Core アプリが受信した元の要求から選択したヘッダーと cookie を渡すことによって、ユーザーの ID を決定するカスタム認証ハンドラーを登録します。

構成

はじめにに従って既に設定されているソリューションでリモート認証を有効にするために必要な小さなコード変更がいくつかあります。

まず、リモート アプリのセットアップ手順に従って、ASP.NET Core と ASP.NET アプリを接続します。 次に、リモート アプリ認証を有効にするために呼び出す追加の拡張メソッドがいくつかあります。

ASP.NET アプリの構成

認証エンドポイントを追加するように ASP.NET アプリを構成する必要があります。 認証エンドポイントを追加するには、AddAuthenticationServer 拡張メソッドを呼び出して、認証エンドポイントへの要求を監視するする HTTP モジュールを設定します。 リモート認証のシナリオでは、認証関連のリダイレクトが ASP.NET アプリではなく、ASP.NET Core アプリに正しくルーティングされるように、通常はプロキシ サポートも追加する必要があります。

SystemWebAdapterConfiguration.AddSystemWebAdapters(this)
    .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 要求を行うという利点があります。

require ブール値に加えて、オプションのコールバックを AddAuthenticationClient に渡して、リモート認証プロセスの動作の他の側面を変更することもできます。

  • RequestHeadersToForward: このプロパティには、認証 API を呼び出すときに要求から転送する必要があるヘッダーが含まれています。 既定では、転送されるヘッダーは AuthorizationCookieのみです。 追加のヘッダーは、この一覧に追加することで転送できます。 または、リストがクリアされている (ヘッダーが指定されていない) 場合は、すべてのヘッダーが転送されます。
  • ResponseHeadersToForward: このプロパティは、ID がチャレンジされるシナリオで認証を要求した元の呼び出しに認証要求から反映する必要がある応答ヘッダーを一覧表示します。 既定では、これには Location ヘッダー、Set-Cookie ヘッダー、および WWW-Authenticate ヘッダーが含まれます。
  • AuthenticationEndpointPath: 認証要求を行う必要がある ASP.NET アプリ上のエンドポイント。 これは、既定で /systemweb-adapters/authenticate であり、ASP.NET 認証エンドポイント構成で指定されたエンドポイントと一致する必要があります。

最後に、ASP.NET Core アプリに以前認証ミドルウェアが含まれていなかった場合は、(ルーティング ミドルウェアの後、承認ミドルウェアの前に) 有効にする必要があります。

app.UseAuthentication();

デザイン

  1. 要求が ASP.NET Core アプリによって処理されると、リモート アプリ認証が既定のスキームであるか、要求のエンドポイントで指定されている場合、RemoteAuthenticationAuthHandler はユーザーの認証を試みます。
    1. ハンドラーは、ASP.NET アプリの認証エンドポイントに対して HTTP 要求を行います。 認証関連データを転送するために、現在の要求からこの新しい要求に構成済みのヘッダーがコピーされます。 前述のように、既定の動作では、Authorize ヘッダーと Cookie ヘッダーをコピーします。 API キー ヘッダーもセキュリティ目的で追加されます。
  2. ASP.NET アプリは、認証エンドポイントに送信された要求を処理します。 API キーが一致する限り、ASP.NET アプリは、応答本文にシリアル化された現在のユーザーの ClaimsPrincipal を返すか、HTTP 状態コード (401 や 302 など) とエラーを示す応答ヘッダーを返します。
  3. ASP.NET Core アプリの RemoteAuthenticationAuthHandler が ASP.NET アプリから応答を受信すると、次のようになります。
    1. ClaimsPrincipal が正常に返された場合、認証ハンドラーはそれを逆シリアル化し、現在のユーザーの ID として使用します。
    2. ClaimsPrincipal が正常に返されなかった場合、ハンドラーは結果を格納し、(たとえば、ユーザーが保護されたリソースにアクセスしているために) 認証がチャレンジされた場合、要求の応答は状態コードと認証エンドポイントからの応答から選択された応答ヘッダーで更新されます。 これにより、チャレンジ応答 (ログイン ページへのリダイレクトなど) をエンド ユーザーに伝達できます。
      1. ASP.NET アプリの認証エンドポイントの結果には、そのエンドポイントに固有のデータが含まれている可能性があるため、ユーザーは、使用する前に認証結果で実行される ASP.NET Core アプリに IRemoteAuthenticationResultProcessor の実装を登録できます。 たとえば、1 つの組み込みの IRemoteAuthenticationResultProcessor は、認証エンドポイントから返された Location 応答ヘッダーを検索し、それらが ASP.NET アプリに直接ではなく、ASP.NET Core アプリのホストに確実にリダイレクトされるようにする RedirectUrlProcessor です。

既知の制限事項

このリモート認証アプローチには、次のいくつかの既知の制限があります。

  1. Windows 認証は Windows ID へのハンドルに依存するため、この機能では Windows 認証はサポートされていません。 今後の作業では、共有 Windows 認証がどのように機能するかを調べる予定です。 詳細については、「dotnet/systemweb-adapters#246」を参照してください。
  2. この機能により、ASP.NET Core アプリは ASP.NET アプリによって認証された ID を利用できますが、ユーザーに関連するすべてのアクション (ログオン、ログオフなど) は、引き続き ASP.NET アプリ経由でルーティングする必要があります。

代替

ASP.NET アプリでの認証が Microsoft.OwinCookie 認証ミドルウェアを使用して行われる場合、ID を共有するための別の解決策は、認証 cookie を共有できるように、ASP.NET アプリと ASP.NET Core アプリを構成することです。 認証 cookie を共有すると、次のことが可能になります。

  • 両方のアプリは、同じ cookie からユーザー ID を決定します。
  • 1 つのアプリにサインインまたはサインアウトすると、ユーザーはもう一方のアプリにサインインまたはサインアウトします。

サインインは通常、特定のデータベースに依存するため、両方のアプリですべての認証機能が機能するわけではないことに注意してください。

  • ユーザーは、ASP.NET アプリまたは ASP.NET Core アプリのいずれか 1 つのアプリを介してのみサインインする必要があります。いずれの場合も、データベースを使用するように設定します。
  • どちらのアプリも、ユーザーの ID と要求を確認できます。
  • どちらのアプリもユーザーをサインアウトできます。

ASP.NET アプリと ASP.NET Core アプリの間で共有認証 cookie を構成する方法の詳細については、 cookie 共有ドキュメントを参照してください。 System.Web アダプター GitHub リポジトリの次のサンプルは、両方のアプリがユーザーのサインインとサインアウトを可能にする共有 cookie 構成を使用したリモート アプリ認証を示しています。

次の両方が当てはまる場合は、認証の共有が適しています。

  • ASP.NET アプリは既に Microsoft.Owincookie 認証を使用しています。
  • 一致するデータ保護設定を使用するように、ASP.NET アプリと ASP.NET Core アプリを更新できます。 共有データ保護設定の照合には、データ保護キーを格納するための共有ファイル パス、Redis キャッシュ、または Azure Blob Storage が含まれます。

その他のシナリオでは、このドキュメントで既に説明したリモート認証アプローチの方が柔軟性が高く、おそらくより適しています。