認証は Web アプリケーションの重要なコンポーネントであり、HTTP 要求全体でユーザー ID 検証を処理します。 ASP.NET Framework から ASP.NET Core に移行する場合、2 つのフレームワークで認証が非常に異なる方法で処理されるため、認証には固有の課題があります。
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 に単に移動できないことを意味します。
認証の種類と移行の課題
さまざまな認証の種類には、さまざまなレベルの移行の複雑さが存在します。
Cookie ベースの認証
-
ASP.NET フレームワーク:
Microsoft.Owincookie 認証ミドルウェアを使用する -
ASP.NET Core: 異なる構成
CookieAuthenticationミドルウェアを使用します - 移行の課題: Cookie 形式、暗号化キー、構成の違い
JWT ベアラー トークン
- ASP.NET フレームワーク: 多くの場合、カスタム モジュールまたは OWIN ミドルウェアによって処理されます
-
ASP.NET Core:
Microsoft.AspNetCore.Authentication.JwtBearerを通じたネイティブ サポート - 移行の課題: トークン検証パラメーターの違いとミドルウェアの登録
Windows 認証
- ASP.NET Framework: 組み込みの IIS 統合
- ASP.NET Core: 明示的な構成が必要であり、ホスティング モデルの変更が必要な場合があります
- 移行の課題: サーバー構成と認証フローの違い
フォーム認証
-
ASP.NET フレームワーク: 組み込み
System.Web.Security.FormsAuthentication - ASP.NET Core: 直接同等の機能はなく、 cookie 認証への移行が必要です
- 移行の課題: 認証システムの書き換えを完了する必要がある
カスタム認証
-
ASP.NET Framework: カスタム モジュールの実装
IHttpModule - ASP.NET Core: カスタム ミドルウェアまたは認証ハンドラー
- 移行の課題: モジュールからミドルウェアへのアーキテクチャの完全な変更
移行戦略の概要
移行中に認証を処理するには、次の 3 つの主な方法があります。
- 完全な書き換え - ASP.NET Core のネイティブ認証を使用するようにすべての認証コードを書き換える
- リモート認証 - System.Web アダプターを使用して、ASP.NET Framework アプリに認証を委任する
- 共有 cookie 認証 - Framework アプリケーションとコア アプリケーション間で認証 Cookie を共有する (OWIN ベースのシナリオの場合)
ほとんどのアプリケーションでは、ネイティブ ASP.NET Core 認証に移行すると、最適なパフォーマンスと保守容易性が提供されます。 ただし、大規模なアプリケーションや複雑な認証要件を持つアプリケーションは、System.Web アダプターを使用した増分アプローチの恩恵を受ける可能性があります。
移行方法を選ぶ
認証を ASP.NET Framework から ASP.NET Core に移行するには、主に 3 つのオプションがあります。 選択は、認証の種類、移行のタイムライン、両方のアプリケーションを同時に実行する必要があるかどうか、および書き換える必要があるコードの量によって異なります。
クイック デシジョン ガイド
次の質問に答えて、アプローチを選択します。
完全な書き換えまたは増分移行を行っていますか?
- 完全な書き換え→ ASP.NET Core 認証への書き換えを完了する
- 段階的移行 → 質問 2に進む
ASP.NET Framework アプリはどの種類の認証を使用しますか?
- OWIN cookie 認証→質問 3 に進む
- リモート認証→フォーム認証、JWT ベアラー トークン、Windows 認証、またはカスタム 認証
ASP.NET Framework アプリと ASP.NET Core アプリの両方が同じ認証状態にアクセスする必要がありますか?
- はい。共有認証が必要→質問 4 に進む
- いいえ。個別の認証は問題ありません→ ASP.NET Core 認証への書き換えを完了します
両方のアプリ間で一致するデータ保護設定を構成できますか?
- はい → 共有 cookie 認証 (代替のセクション、最適なパフォーマンスを参照)
- リモート認証→しないか不明
移行アプローチの比較
| 方法 | コードの変更 | [パフォーマンス] | 認証の共有 | 使用するタイミング |
|---|---|---|---|---|
| 書き換えを完了する | 高 - すべての認証コードを書き換える | 最高 | 無し | 完全な書き換え、パフォーマンスが重要なアプリ、OWIN 以外の認証 |
| リモート認証 | 低 - 既存のパターンを保持する | 普通 | 完全 | 増分移行、複雑な認証、Windows 認証 |
| 共有クッキー | 中 - 構成の更新 | よし | 完全 | OWIN cookie 認証、パフォーマンスクリティカルな共有認証 (代替を参照) |
ASP.NET Core 認証への書き換えを完了する
完全な移行を実行する場合、OWIN 以外の認証を使用する場合、または最適なパフォーマンスと保守容易性が必要な場合は、この方法を選択します。
ASP.NET Core は、高パフォーマンスで広範なカスタマイズ オプションを備えた包括的な認証サポートを提供します。 この方法では認証コードを書き換える必要がありますが、長期的には最も利点があります。
完全な書き換えの長所と短所
| 利点 | 短所 |
|---|---|
| 最高のパフォーマンスとセキュリティ | すべての認証コードを書き直す必要があります |
| ネイティブ ASP.NET Core の実装 | 自動移行パスなし |
| 認証フローを完全に制御する | 新しい認証パターンの学習曲線 |
| 追加の依存関係なし | Framework パターンの破壊的変更 |
| 最新の ASP.NET コア認証機能へのアクセス | 移行中の潜在的なダウンタイム |
移行に関する考慮事項
ネイティブ ASP.NET Core 認証に移行する場合:
フレームワーク認証の種類に基づいて選択します。
- フォーム認証→ Cookie 認証に移行する
- JWT ベアラートークンからJWT ベアラー認証への移行
- Windows 認証 → Windows 認証を使用する
- OWIN OAuth プロバイダー →対応する ASP.NET Core OAuth プロバイダーを使用する
- カスタム認証 → カスタム認証ハンドラーを実装する
コードの変更が必要です。
-
HttpContext.Userアクセス パターンを置き換える (ほとんど互換性があります) - で認証ミドルウェアの登録を更新する
Program.cs - カスタム認証ロジックを ASP.NET Core パターンに移行する
- 承認属性とポリシーを更新する
この方法を選択する場合:
- 認証関連のコードを書き換える余裕がある
- パフォーマンスが最優先事項
- レガシ アプリケーションと認証状態を共有していない
- System.Web の依存関係を完全に排除する必要がある
- フレームワーク アプリで Forms 認証、カスタム モジュール、または JWT トークンを使用する
リモート認証
注
これにより、 System.Web アダプター を使用して移行が簡略化されます。
この方法は、増分移行中に ASP.NET Framework と ASP.NET Core アプリケーションの間で認証を共有する必要がある場合、または移行が困難な複雑な認証がある場合に選択します。
System.Web アダプターのリモート認証機能を使用すると、ASP.NET Core アプリは ASP.NET アプリを介してユーザーの ID を認証できます。 これにより、1 つの認証システムを維持しながら段階的な移行が可能になります。
リモート認証のしくみ
- ASP.NET Core アプリによって要求が処理されると、リモート アプリ認証が既定のスキームであるか、要求のエンドポイントで指定されている場合、
RemoteAuthenticationAuthHandlerはユーザーの認証を試みます。 - ハンドラーは、ASP.NET アプリの認証エンドポイントに HTTP 要求を行い、構成済みのヘッダーを現在の要求 (既定では、
AuthorizationヘッダーとCookieヘッダー) から転送します。 - ASP.NET アプリは認証を処理し、シリアル化された
ClaimsPrincipalまたは失敗を示す HTTP 状態コードを返します。 - ASP.NET Core アプリでは、結果を使用してユーザーの ID を確立するか、認証チャレンジを処理します。
リモート認証の長所と短所
| 利点 | 短所 |
|---|---|
| 最小限のコード変更が必要 | 追加の HTTP 要求のオーバーヘッド |
| 任意のフレームワーク認証の種類で動作します | アプリ間のネットワーク依存関係 |
| 段階的な移行機能 | より複雑なデバッグ |
| 既存の認証ロジックを保持する | 両方のアプリが実行されている必要がある |
| 複雑な認証シナリオを処理する | Windows 認証の限定的サポート |
リモート認証を選択するタイミング
次の場合にリモート認証を選択します。
- ASP.NET アプリで
Microsoft.Owincookie 認証が使用されていない - さまざまな認証メカニズムで動作する柔軟なソリューションが必要です
- 認証ロジックを ASP.NET Core に段階的に移行する必要がある
- 書き換えが困難な複雑なカスタム認証がある
- 増分移行をしているため、共有認証状態が必要です
リモート認証の構成
概要に従って既に設定されているソリューションでリモート認証を有効にするために必要な小さなコード変更がいくつかあります。
まず、 リモート アプリのセットアップ 手順に従って、ASP.NET Core と ASP.NET アプリを接続します。 その後、リモート アプリ認証を有効にするために呼び出す追加の拡張メソッドがいくつかあります。
ASP.NET アプリの構成
認証エンドポイントを追加するには、ASP.NET アプリを構成する必要があります。 認証エンドポイントを追加するには、 AddAuthenticationServer 拡張メソッドを呼び出して、認証エンドポイントへの要求を監視する HTTP モジュールを設定します。 リモート認証のシナリオでは、通常、プロキシのサポートも追加して、認証関連のリダイレクトが ASP.NET ではなく、ASP.NET Core アプリに正しくルーティングされるようにする必要があることに注意してください。
HttpApplicationHost.RegisterHost(builder =>
{
builder.AddSystemWebAdapters()
.AddProxySupport(options => options.UseForwardedHeaders = true)
.AddRemoteAppServer(options =>
{
options.ApiKey = ConfigurationManager.AppSettings["RemoteAppApiKey"];
})
.AddAuthenticationServer();
});
ASP.NET Core アプリの構成
次に、ASP.NET アプリに HTTP 要求を行ってユーザーを認証する認証ハンドラーを有効にするように、ASP.NET Core アプリを構成する必要があります。 ここでも、これは 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 アプリにリモート認証を使用する場合は、フォールバック要求でリモート認証が呼び出されないようにします。 フォールバック中にリモート認証を実行すると、アプリは不要な追加の呼び出しをフレームワーク アプリに戻し、混乱を招く可能性があります。
フォールバック要求に対してリモート認証を実行しないようにするには、次のいずれかの方法を使用します。
- ルートがミドルウェア パイプラインの残りの部分をバイパスするように、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 Core ミドルウェアに関するページを参照してください。
app.UseAuthentication();
セキュリティに関する考慮事項
リモート認証を実装する場合は、次のセキュリティ面を考慮してください。
- API キーのセキュリティ: ASP.NET Core アプリと ASP.NET アプリの間の通信に使用される API キーは、ハードコーディングではなく 、構成プロバイダー を使用して安全に格納する必要があります。
- ネットワーク セキュリティ: 運用環境では、セキュリティで保護されたチャネル (HTTPS) 経由でアプリ間の通信が行われる必要があります。
- ヘッダー転送: 機密情報が公開されないように、転送するヘッダーには注意してください。 認証に必要なヘッダーのみを転送します。
- Endpoint Protection: ASP.NET アプリの認証エンドポイントには、外部クライアントではなく、ASP.NET Core アプリからのみアクセスできるようにする必要があります。
トラブルシューティング
リモート認証を構成するときの一般的な問題:
- 認証エラー: API キーが両方のアプリケーション間で一致し、認証エンドポイント パスが正しく構成されていることを確認します。
-
リダイレクト ループ: ASP.NET アプリではなく、ASP.NET Core アプリにリダイレクトするように
RedirectUrlProcessorが適切に構成されていることを確認します。 -
不足している要求: ASP.NET アプリが
ClaimsPrincipalを正しくシリアル化していること、および必要なすべての要求が含まれていることを確認します。
設計
- ASP.NET Core アプリによって要求が処理されると、リモート アプリ認証が既定のスキームであるか、要求のエンドポイントで指定されている場合、
RemoteAuthenticationAuthHandlerはユーザーの認証を試みます。- ハンドラーは、ASP.NET アプリの認証エンドポイントに HTTP 要求を行います。 認証関連データを転送するために、現在の要求からこの新しい要求に構成済みのヘッダーがコピーされます。 前述のように、既定の動作では、
AuthorizationヘッダーとCookieヘッダーがコピーされます。 API キー ヘッダーもセキュリティ目的で追加されます。
- ハンドラーは、ASP.NET アプリの認証エンドポイントに HTTP 要求を行います。 認証関連データを転送するために、現在の要求からこの新しい要求に構成済みのヘッダーがコピーされます。 前述のように、既定の動作では、
- ASP.NET アプリは、認証エンドポイントに送信された要求を処理します。 API キーが一致する限り、ASP.NET アプリは現在のユーザーの ClaimsPrincipal を応答本文にシリアル化するか、HTTP 状態コード (401 や 302 など) とエラーを示す応答ヘッダーを返します。
- ASP.NET Core アプリの
RemoteAuthenticationAuthHandlerが ASP.NET アプリから応答を受信すると、次のようになります。- ClaimsPrincipal が正常に返された場合、認証ハンドラーはそれを逆シリアル化し、現在のユーザーの ID として使用します。
- ClaimsPrincipal が正常に返されなかった場合、ハンドラーは結果を格納し、認証がチャレンジされた場合 (たとえば、ユーザーが保護されたリソースにアクセスしているため)、要求の応答は状態コードと認証エンドポイントからの応答から選択された応答ヘッダーで更新されます。 これにより、チャレンジ応答 (ログイン ページへのリダイレクトなど) をエンド ユーザーに伝達できます。
- ASP.NET アプリの認証エンドポイントからの結果には、そのエンドポイントに固有のデータが含まれる場合があるため、ユーザーは、
IRemoteAuthenticationResultProcessor実装を ASP.NET Core アプリに登録できます。この実装は、使用する前に認証結果で実行されます。 たとえば、1 つの組み込みのIRemoteAuthenticationResultProcessorは、認証エンドポイントから返されたRedirectUrlProcessor応答ヘッダーを検索し、それらが ASP.NET アプリに直接ではなく、ASP.NET Core アプリのホストに確実にリダイレクトされるようにするLocationです。
- ASP.NET アプリの認証エンドポイントからの結果には、そのエンドポイントに固有のデータが含まれる場合があるため、ユーザーは、
既知の制限事項
このリモート認証アプローチには、いくつかの既知の制限があります。
- Windows 認証: Windows 認証は Windows ID のハンドルに依存するため、この機能では Windows 認証はサポートされていません。 今後の作業では、共有 Windows 認証がどのように機能するかを調べる予定です。 詳細については、 dotnet/systemweb-adapters#246 を参照してください。 Windows 認証シナリオでは、代わりに ASP.NET Core アプリケーションで ASP.NET Core で Windows 認証を構成 することを検討してください。
- ユーザー管理アクション: この機能により、ASP.NET Core アプリは、ASP.NET アプリによって認証された ID を利用できますが、ユーザーに関連するすべてのアクション (ログオン、ログオフなど) は、引き続き ASP.NET アプリ経由でルーティングする必要があります。
- パフォーマンスに関する考慮事項: 各認証要求には、ASP.NET アプリへの HTTP 呼び出しが必要であり、パフォーマンスに影響を与える可能性があります。 パフォーマンスが重要な場合は、共有 cookie 認証を使用することを検討してください (代替のセクションで説明)。
共有 cookie 認証
ASP.NET アプリの認証が Microsoft.OwinCookie 認証ミドルウェアを使用して行われる場合、リモート認証の代替ソリューションは、認証 cookieを共有できるように、ASP.NET と ASP.NET Core アプリを構成することです。
共有 Cookie のしくみ
認証 cookie を共有すると、次のことが可能になります。
- 同じ cookieからユーザー ID を決定する両方のアプリ。
- 1 つのアプリにサインインまたはサインアウトすると、ユーザーはもう一方のアプリにサインインまたはサインアウトします。
どちらのアプリケーションも、次の構成が行われます。
- 同じ cookie 名とドメイン設定を使用する
- cookie暗号化/暗号化解除用のデータ保護キーを共有する
- 互換性のある cookie 認証ミドルウェアを使用する
これにより、1 つのアプリで認証されたユーザーは、要求を行うときに、もう一方のアプリで自動的に認証されます。
共有 cookie 認証の長所と短所
| 利点 | 短所 |
|---|---|
| 共有認証に最適なパフォーマンス | OWIN cookie 認証でのみ機能します |
| 追加の HTTP 要求なし | 一致するデータ保護のセットアップが必要 |
| どちらのアプリもサインイン/サインアウトを処理できます | より複雑な初期構成 |
| シームレスなユーザー エクスペリエンス | cookie ベースの認証に限定 |
| ネットワーク オーバーヘッドの削減 | デプロイの調整が必要 |
共有 Cookie に関する認証の制限事項
通常、サインインは特定のデータベースに依存するため、両方のアプリですべての認証機能が機能するわけではありません。
- ユーザーは、ASP.NET または ASP.NET Core アプリのいずれか 1 つのアプリを介してのみサインインする必要があります。どちらの場合でも、データベースを操作するように設定します。
- どちらのアプリも、ユーザーの ID と要求を表示できます。
- どちらのアプリもユーザーをサインアウトできます。
ASP.NET と ASP.NET Core アプリの間で共有認証 Cookie を構成する方法の詳細については、 cookie 共有ドキュメントを参照してください。 ASP.NET Core での認証cookieの詳細については、「ASP.NET Core cookieなしでIdentity認証を使用する」を参照してください。 Framework アプリと Core アプリ間で保護された値を共有するときの <machineKey> とデータ保護の構成に関するガイダンスについては、「 ASP.NET の machineKey を ASP.NET Core への移行」を参照してください。
System.Web アダプター GitHub リポジトリの次のサンプルでは、共有cookie構成を使用してリモート アプリ認証を行い、両方のアプリでユーザーのサインインとサインアウトを行うことができます。
共有 cookie 認証を選択するタイミング
次の場合は、[共有 Cookie 認証] を選択します。
- ASP.NET アプリで既に
Microsoft.Owincookie 認証が使用されている - 両方のアプリ間で一致するデータ保護設定を構成できます
- パフォーマンスは重要であり、HTTP 要求を最小限に抑える必要がある
- 両方のアプリでユーザーのサインイン/サインアウト操作を処理する
- 共有暗号化キーの管理に慣れている
次の両方に該当する場合は、認証の共有が適しています。
- ASP.NET アプリは既に
Microsoft.Owincookie 認証を使用しています。 - 一致するデータ保護設定を使用するように、ASP.NET アプリと ASP.NET Core アプリを更新できます。 一致する共有データ保護設定には、データ保護キーを格納するための共有ファイル パス、Redis Cache、または Azure Blob Storage が含まれます。 詳細については、「ASP.NET Core のデータ保護の概要」を参照してください。
その他のシナリオでは、このドキュメントで前述したリモート認証アプローチの方が柔軟性が高く、おそらくより適しています。
こちらも参照ください
ASP.NET Core