クイック スタート: ASP.NET Core Web API を保護する

このクイック スタートでは、Microsoft.Identity.Web を使用して Microsoft Entra ID により ASP.NET Core Web API を保護します。 ベアラー トークンを検証し、承認された呼び出し元へのアクセスを制限する認証ミドルウェアを追加します。

Azure サブスクリプションをお持ちでない場合は、開始する前に 無料アカウント を作成してください。

前提条件

オプション 1: テンプレートから作成する (最速)

ASP.NET Core テンプレートと組み込みのMicrosoft Entra認証を使用して、保護された API プロジェクトをスキャフォールディングします。

1.プロジェクトを作成する

次のコマンドを実行して、単一組織認証を使用して新しい Web API プロジェクトを作成し、プロジェクト ディレクトリに移動します。

dotnet new webapi --auth SingleOrg --name MyWebApi
cd MyWebApi

2.アプリの登録を構成する

appsettings.json のプレースホルダーの値を、Microsoft Entra アプリの登録の詳細に置き換えます。

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "your-tenant-id",
    "ClientId": "your-api-client-id"
  }
}

3. API を実行する

アプリケーションを起動します。

dotnet run

これで API が https://localhost:5001で保護されるようになりました。

完了! 要求には有効なアクセス トークンが必要になりました。


オプション 2: 既存の Web API に追加する

ASP.NET Core Web API が既にある場合は、次の手順でMicrosoft Entra認証を追加します。

1. NuGet パッケージをインストールする

プロジェクトに Microsoft.Identity.Web NuGet パッケージを追加します。

dotnet add package Microsoft.Identity.Web

2. Program.csで認証を構成する

アプリのスタートアップ パイプラインに認証サービスと承認サービスを登録します。 次のコードは、Microsoft Entra検証を使用して JWT ベアラー認証を構成します。

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;

var builder = WebApplication.CreateBuilder(args);

// Add authentication
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddMicrosoftIdentityWebApi(builder.Configuration, "AzureAd");

// Add authorization
builder.Services.AddAuthorization();

builder.Services.AddControllers();

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthentication(); //  Add authentication middleware
app.UseAuthorization();

app.MapControllers();

app.Run();

3. 設定を追加する appsettings.json

テナントとアプリケーションの詳細を含むMicrosoft Entra構成セクションを追加します。 トークン検証の問題のトラブルシューティングに役立つ、Microsoft.Identity.Web のログ レベルを Information に設定します。

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "your-tenant-id",
    "ClientId": "your-api-client-id"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.Identity.Web": "Information"
    }
  }
}

4. API エンドポイントを保護する

有効なアクセス トークンを必要とするコントローラーまたはアクションに [Authorize] 属性を適用します。

すべてのエンドポイントに対して認証を要求する:

次のコントローラーは、すべてのアクションに対して有効なアクセス トークンを必要とし、ユーザー要求にアクセスする方法を示しています。

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

[Authorize] //  Require valid access token
[ApiController]
[Route("api/[controller]")]
public class WeatherForecastController : ControllerBase
{
    [HttpGet]
    public IEnumerable<WeatherForecast> Get()
    {
        // Access user information
        var userId = User.FindFirst("oid")?.Value;
        var userName = User.Identity?.Name;

        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
            TemperatureC = Random.Shared.Next(-20, 55),
            Summary = "Protected data"
        });
    }
}

特定のスコープが必要です。

[RequiredScope]属性を使用して、個々のアクションにきめ細かなアクセス許可を適用します。

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Identity.Web;

[Authorize]
[ApiController]
[Route("api/[controller]")]
public class TodoController : ControllerBase
{
    [HttpGet]
    [RequiredScope("access_as_user")] //  Require specific scope
    public IActionResult GetAll()
    {
        return Ok(new[] { "Todo 1", "Todo 2" });
    }

    [HttpPost]
    [RequiredScope("write")] //  Different scope for write operations
    public IActionResult Create([FromBody] string item)
    {
        return Created("", item);
    }
}

5. 実行とテスト

アプリケーションを起動し、認証されていない要求が拒否されることを確認します。

dotnet run

Postman や curl などのツールを使用してテストします。 認証されていない要求は、次の 401 Unauthorizedを返します。

curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" https://localhost:5001/api/weatherforecast

成功しました! これで、API によってベアラー トークンが検証されるようになりました。


アプリの登録のセットアップ

API でトークンを検証するには、Microsoft Entraアプリの登録が必要です。 Azure ポータルで次の手順に従います。

1. API を登録する

  1. Azure ポータル
  2. Microsoft Entra ID>のアプリ登録>の新しい登録に移動します。
  3. 名前を入力します (例: "My Web API")
  4. シングル テナントを選択する (API で最も一般的)
  5. API にリダイレクト URI は必要ありません
  6. [登録] をクリックします。

2. API スコープを公開する

API を呼び出すときにクライアント アプリが要求できるアクセス許可 (スコープ) を定義します。

  1. API アプリの登録で、[API の公開] に移動します
  2. [スコープの追加] をクリックする
  3. 既定のアプリケーション ID URI をそのまま使用するか、カスタマイズします (例: api://your-api-client-id)
  4. スコープを追加します。
    • スコープ名:access_as_user
    • 同意できるユーザー: 管理者とユーザー
    • 管理者の同意の表示名: "Access My Web API"
    • 管理者の同意の説明: "サインインしているユーザーの代わりにアプリが Web API にアクセスできるようにする"
  5. [スコープの追加] をクリックする

3. アプリケーション ID をメモする

アプリ登録の概要ページから アプリケーション (クライアント) ID を コピーします。 この値はappsettings.jsonClientIdにあります。


クライアント アプリの登録を作成する (テスト用)

保護された API をテストするには、トークンを取得して API を呼び出す別のクライアント アプリケーションを登録します。

1. クライアント アプリケーションを登録する

  1. Microsoft Entra ID>アプリの登録 で、別の登録を作成します
  2. 名前を付けます (例: "My API Client")
  3. アカウントの種類の選択
  4. リダイレクト URI の追加: https://localhost:7000/signin-oidc (Web アプリの場合)
  5. [登録] をクリックします。

2. API のアクセス許可を付与する

定義したスコープで API を呼び出すアクセス許可をクライアント アプリケーションに付与します。

  1. クライアント アプリの登録で、API のアクセス許可に移動します
  2. [アクセス許可の追加] をクリックします>マイ API
  3. API 登録を選択する
  4. access_as_userスコープを確認する
  5. [アクセス許可の追加] をクリックする
  6. [ 管理者の同意を付与] をクリックします (必要な場合)

3. クライアント シークレットを作成する (機密クライアントの場合)

クライアント アプリが (ブラウザーやモバイル デバイスではなく) サーバー上で実行されている場合は、認証用のクライアント シークレットを作成します。

  1. 証明書とシークレットに移動します
  2. [新しいクライアント シークレット] をクリックする
  3. 説明と有効期限を追加する
  4. [追加] をクリックします。
  5. シークレット値をすぐにコピー します。もう一度表示することはできません

保護された API をテストする

認証された要求を送信して、API がトークンを正しく検証することを確認します。

Postman の使用

トークンを取得して API を呼び出すように、Postman で OAuth 2.0 認証を設定します。

  1. Postman で新しい要求を作成する
  2. OAuth 2.0 認証を設定します。
    • 許可の種類: 承認コード (ユーザー コンテキストの場合) またはクライアント資格情報 (アプリ コンテキストの場合)
    • 認証 URL:https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/authorize
    • アクセス トークン URL:https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token
    • クライアント ID: クライアント アプリのクライアント ID
    • クライアント シークレット: クライアント アプリのシークレット
    • スコープ:api://your-api-client-id/access_as_user
  3. [Get New Access Token]\(新しいアクセス トークンの取得\) を
  4. トークンを使用して API を呼び出す

コードの使用 (C# の例)

次の例では、MSAL.NET を使用して、クライアント資格情報フローを使用してトークンを取得し、保護された API を呼び出します。

// In a console app or client application
using Microsoft.Identity.Client;

var app = ConfidentialClientApplicationBuilder
    .Create("client-app-id")
    .WithClientSecret("client-secret")
    .WithAuthority("https://login.microsoftonline.com/{tenant-id}")
    .Build();

var result = await app.AcquireTokenForClient(
    new[] { "api://your-api-client-id/.default" }
).ExecuteAsync();

var accessToken = result.AccessToken;

// Use the token to call your API
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", accessToken);

var response = await client.GetAsync("https://localhost:5001/api/weatherforecast");

一般的な構成オプション

Microsoft。Identity.Web では、さまざまなシナリオで複数の構成パターンがサポートされています。

構成で特定のスコープを要求する

[RequiredScope]属性を使用する代わりに、appsettings.jsonで必要なスコープをグローバルに構成できます。

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "your-tenant-id",
    "ClientId": "your-api-client-id",
    "Scopes": "access_as_user"
  }
}

複数のテナントからのトークンを受け入れる

任意のMicrosoft Entra テナントからトークンを受け入れるには、TenantIdcommon に設定します。

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "common",
    "ClientId": "your-api-client-id"
  }
}

トークンの検証を構成する

API がダウンストリーム API (Microsoft Graph など) を呼び出す場合は、トークンの取得を有効にして、トークン キャッシュを構成します。

builder.Services.AddMicrosoftIdentityWebApiAuthentication(builder.Configuration)
    .EnableTokenAcquisitionToCallDownstreamApi() // If your API calls other APIs
    .AddInMemoryTokenCaches();

次のステップ

保護された API が作成されたので、次のトピックを参照してください。

Troubleshooting

401 権限がありません

問題: API は、トークンを使用しても 401 を返します。

考えられる原因:

  • トークンの対象ユーザー (aud 要求) が API の対象ユーザーと一致しない ClientId
  • トークンの有効期限が切れています
  • トークンが間違ったテナント用である
  • 必要なスコープがありません

ソリューション: jwt.ms でトークン デコードし、要求を確認します。 詳細なトラブルシューティングについては、「 ログ記録と診断 」を参照してください。

AADSTS50013: 無効な署名

問題: トークン署名の検証が失敗します。

ソリューション:TenantIdClientIdが正しいことを確認します。 トークンは、予想される機関によって発行される必要があります。 詳細なログ記録を有効にして、検証エラーを確認します。

トークンにスコープが見つかりません

問題:[RequiredScope] 属性は失敗します。

Solution:

  1. クライアント アプリにスコープへのアクセス許可があることを確認する
  2. 管理者の同意が付与されていることを確認する (必要な場合)
  3. 完全なスコープ検証パターンについては、 承認ガイド を参照してください
  4. トークンを取得するときにスコープが要求されていることを確認します (例: api://your-api/.default または特定のスコープ)

詳細:Web API トラブルシューティング ガイド