保護された Web API: コード構成

保護された Web API のコードを構成するには、次の点を理解しておいてください。

  • API を保護対象として定義するもの
  • ベアラー トークンの構成方法
  • トークンの検証方法

ASP.NET と ASP.NET Core の API を保護対象として定義するものとは

Web アプリと同じように、ASP.NET と ASP.NET Core の Web API は、そのコントローラー アクションに [Authorize] 属性のプレフィックスがあるため、保護されています。 コントローラー アクションは、承認されている ID で API が呼び出された場合にのみ呼び出すことができます。

次の質問について考えてみましょう。

  • Web API を呼び出せるのはアプリのみです。 API では、呼び出し元のアプリの ID をどのように認識しますか?
  • ユーザーの代わりにアプリで API が呼び出される場合、ユーザーの ID は何ですか?

ベアラー トークン

アプリが呼び出されたときにヘッダーに設定されるベアラー トークンには、アプリ ID に関する情報が保持されます。 また、Web アプリがデーモン アプリからのサービス間の呼び出しを受け入れる場合を除き、ユーザーに関する情報も保持されます。

これは、Microsoft Authentication Library for .NET (MSAL.NET) を使用してトークンを取得した後、API を呼び出すクライアントを示す C# コードの例です。

var scopes = new[] {$"api://.../access_as_user"};
var result = await app.AcquireToken(scopes)
                      .ExecuteAsync();

httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);

// Call the web API.
HttpResponseMessage response = await _httpClient.GetAsync(apiUri);

重要

クライアント アプリケーションにより、"Web API の" Microsoft ID プラットフォームにベアラー トークンが要求されます。 API は、トークンを検証し、含まれている要求を表示する必要がある唯一のアプリケーションです。 クライアント アプリで、トークンの要求を検査してみることはできません

将来、Web API で、トークンの暗号化が要求される可能性があります。 この要件により、アクセス トークンを表示できるクライアント アプリのアクセスが禁止されます。

JwtBearer の構成

このセクションでは、ベアラー トークンの構成方法について説明します。

config ファイル

1 つのテナント (基幹業務アプリ) からのアクセス トークンを受け入れる場合にのみ TenantId を指定する必要があります。 それ以外の場合、common のままにできます。 異なる値には、次の値を指定できます。

  • GUID (テナント ID = ディレクトリ ID)
  • common は、任意の組織アカウントと個人アカウントにすることができます
  • organizations は、任意の組織にできます
  • consumers は、Microsoft 個人アカウントです
{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "ClientId": "Enter_the_Application_(client)_ID_here",
    "TenantId": "common"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*"
}

Web API にカスタム アプリ ID URI を使用する

Azure portal によって提案された既定のアプリ ID URI を受け入れた場合は、対象ユーザーを指定する必要はありません (「アプリケーション ID の URI とスコープ」を参照してください)。 それ以外の場合は、Web API のアプリ ID URI を値とする Audience プロパティを追加します。 これは通常、api:// で始まります。

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "ClientId": "Enter_the_Application_(client)_ID_here",
    "TenantId": "common",
    "Audience": "Enter_the_Application_ID_URI_here"
  },
}

コードの初期化

[Authorize] 属性を保持するコントローラー アクションでアプリが呼び出されると、ASP.NET と ASP.NET Core により、Authorization ヘッダーのベアラー トークンからアクセス トークンが抽出されます。 その後、アクセス トークンは JwtBearer ミドルウェアに転送され、Microsoft IdentityModel Extensions for .NET が呼び出されます。

Microsoft.Identity.Web

ASP.NET Core で Web API を開発する場合は、Microsoft.Identity.Web NuGet パッケージを使用することをお勧めします。

Microsoft.Identity.Web を使用すると、ASP.NET Core、認証ミドルウェア、および .NET 用の Microsoft Authentication Library (MSAL) 間を結び付けることができます。 これにより、より明確で堅牢な開発者エクスペリエンスが可能になり、Microsoft ID プラットフォームと Azure AD B2C の機能を活用できます。

.NET 6.0 用 ASP.NET

Microsoft.Identity.Web を使う新しい Web API プロジェクトを作成するには、.NET 6.0 CLI または Visual Studio でプロジェクト テンプレートを使います。

.NET Core CLI

# Create new web API that uses Microsoft.Identity.Web
dotnet new webapi --auth SingleOrg

Visual Studio - Visual Studio で Web API プロジェクトを作成するには、[ファイル]>[新規作成]>[プロジェクト]>[ASP.NET Core Web API] を選択します。

.NET CLI と Visual Studio の両方のプロジェクト テンプレートで、このコード スニペットのような Program.cs ファイルが作成されます。 Microsoft.Identity.Web using ディレクティブと、認証と承認を含む行に注目してください。

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

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();