ASP.NET Core での API エンドポイント認証の動作

cookie認証を使用すると、認証されていない要求をログイン ページにリダイレクトするのではなく、API エンドポイントから認証エラーに対して適切な HTTP 状態コード (401 または 403) が返されます。 この動作は、プログラムによる API アクセスに適しており、.NET 10 の ASP.NET Core で導入されました。

ASP.NET Core で API エンドポイントを識別する方法

ASP.NET Coreは、次のような API エンドポイントとして認識されるエンドポイントにIDisableCookieRedirectMetadataを追加します。

  • [ApiController]属性で修飾されたコントローラー。
  • JSON 要求本文を読み取ったり、JSON 応答を書き込んだりする最小限の API エンドポイント。
  • TypedResults型の戻り値を使用するエンドポイント。
  • SignalR ハブとエンドポイント。

検出は、アプリがエンドポイントを構築するときに推論されるメタデータに基づいています。 これは、受信要求の Accept ヘッダーに基づくのではなく、ルートを登録した Map{Verb} メソッドに基づいていません。

宣言された戻り値の型がvoid、string、またはIResult インターフェイスである最小限の API ハンドラーは、戻り値の型を通じてメタデータを提供しませんが、Ok<TValue>などの具体的なTypedResults型は提供します。 たとえば、 app.MapGet("/hello", () => "Hello").RequireAuthorization() は text/plain 応答を書き込み、JSON 要求本文を受け取らないため、認証されていない要求はログイン ページにリダイレクトされます。

既定の動作

既定では、ASP.NET Core では、エンドポイントの種類 cookie 基づいて認証ロジックが適用されます。

  • Web ページ: 302 状態コードを使用してログインまたはアクセス拒否ページにリダイレクトします。
  • API エンドポイント: 302 リダイレクトではなく、401 または 403 の状態コードを返します。

XMLHttpRequests (XR) は 、対象となるエンドポイントに関係なく、401 と 403 の応答を受け取ります。 この動作は .NET 10 より前から存在しており、変更されていません。

Note

エンドポイント メタデータはチャレンジ (401) と禁止 (403) パスにのみ影響します。 サインアウト リダイレクトは影響を受けません。 サインアウト要求でリダイレクト URI または有効な戻り URL が指定されている場合、XHR 以外の要求は 10 .NET前と同様にリダイレクトされます。 XHR 動作は変更されません。

特定のエンドポイントの動作を構成する

DisableCookieRedirectを呼び出して、自動的に検出されないエンドポイントの状態コード 401 と 403 を返します。

var api = app.MapGroup("/api").DisableCookieRedirect();

api.MapGet("/status", () => "Ready")
   .RequireAuthorization();

AllowCookieRedirectを呼び出して、API エンドポイントとして検出されたエンドポイントのログイン リダイレクトを保持します。

app.MapGet("/reports/summary", () => new { Total = 1000 })
   .RequireAuthorization()
   .AllowCookieRedirect();

コントローラーの場合は、アクション メソッドまたはコントローラー クラスに AllowCookieRedirectAttribute を適用します。

[ApiController]
[Authorize]
[AllowCookieRedirect]
[Route("[controller]")]
public class ReportsController : ControllerBase
{
    [HttpGet("summary")]
    public object GetSummary() => new { Total = 1000 };
}

Important

IAllowCookieRedirectMetadata は、メタデータが追加される順序に関係なく、 IDisableCookieRedirectMetadata をオーバーライドします。 同じエンドポイントでAllowCookieRedirectした後にDisableCookieRedirectを呼び出しても、状態コードの動作は復元されません。

アプリ全体で動作をオプトアウトする

アプリ全体に対して .NET 10 より前の動作を復元するには、Microsoft.AspNetCore.Authentication.Cookies.IgnoreRedirectMetadata スイッチを有効にします。 有効にすると、cookie 認証ではエンドポイントのメタデータが無視され、XHR のみが 401 および 403 応答を返します。

アプリ コードが実行される前に適用されるように、プロジェクト ファイルでスイッチを設定します。

<ItemGroup>
  <RuntimeHostConfigurationOption
    Include="Microsoft.AspNetCore.Authentication.Cookies.IgnoreRedirectMetadata"
    Value="true" />
</ItemGroup>

スイッチはコードで設定することもできます。 cookie認証が初めて使用されるときに 1 回読み取られるので、ホストがビルドされる前にSetSwitchを呼び出します。

AppContext.SetSwitch(
    "Microsoft.AspNetCore.Authentication.Cookies.IgnoreRedirectMetadata", true);

var builder = WebApplication.CreateBuilder(args);

破壊的変更に関する考慮事項

.NET 10 で導入された変更は、動作の変化です。 cookie 認証と、ASP.NET Core が API エンドポイントとして検出するエンドポイントを組み合わせたアプリでは、以前はログイン ページまたはアクセス拒否ページへの 302 リダイレクトを返していましたが、401 応答および 403 応答を返すようになります。 完全な破壊的変更のお知らせについては、Cookie既知の API エンドポイントではログイン リダイレクトが無効 を参照してください。

各種類のアプリへの影響を考慮してください。

  • Web アプリケーション: ページ エンドポイントは引き続きログイン ページにリダイレクトされます。
  • 混合アプリケーション: API エンドポイントは、Web ページがリダイレクトを取得するときに状態コードを返します。そのため、リダイレクトに続くブラウザー コードでは、代わりに 401 と 403 を処理する必要があります。
  • API 専用アプリケーション: 検出された API エンドポイントは、追加の構成なしで適切な HTTP 状態コードを返します。

以前の動作を維持するには、影響を受けるエンドポイントで AllowCookieRedirect を呼び出すか、影響を受けるコントローラーに [AllowCookieRedirect] を適用するか、アプリ全体の Microsoft.AspNetCore.Authentication.Cookies.IgnoreRedirectMetadata スイッチを有効にします。

API エンドポイントのテスト

.NET 10 の ASP.NET Coreにアップグレードした後、API エンドポイントから適切な状態コードが返されることを確認します。

[Fact]
public async Task UnauthorizedApiRequest_Returns401()
{
    var response = await client.GetAsync("/api/secure-data");

    Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);

    // The handler sets the Location header before setting the status code,
    // so the login URI is still present on the 401 response.
    Assert.NotNull(response.Headers.Location);
}