保護された 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();
トークンの検証
前のスニペットでは、Web アプリの OpenID Connect ミドルウェアと同様に、JwtBearer ミドルウェアによって TokenValidationParameters
の値に基づいてトークンが検証されます。 トークンは必要に応じて暗号化が解除され、要求が抽出され、署名が検証されます。 その後、ミドルウェアでは、このデータを調べてトークンを確認します。
- Audience:トークンが Web API のターゲットとなっていること。
- サブ:Web API の呼び出しが許可されているアプリに対して発行されたこと。
- 発行者:信頼できるセキュリティ トークン サービス (STS) によって発行されたこと。
- 有効期限:有効期間が範囲内であること。
- 署名:改ざんされていないこと。
特別な検証もできます。 たとえば、署名キー (トークンに埋め込まれている場合) が信頼されていること、およびトークンが再生されていないことを確認することができます。 最後に、一部のプロトコルでは、特定の検証が必要です。
検証コントロール
確認手順は、検証コントロールでキャプチャされます。これらは Microsoft IdentityModel Extensions for .NET のオープン ソース ライブラリで提供されています。 検証コントロールは、ライブラリ ソース ファイル Microsoft.IdentityModel.Tokens/Validators.cs で定義されています。
次の表では、検証コントロールについて説明します。
検証コントロール | 説明 |
---|---|
ValidateAudience | トークンが、自分のトークンを確認するアプリケーション用であることを保証します。 |
ValidateIssuer | トークンが信頼できる STS、つまり自分が信頼する人から発行されたことを保証します。 |
ValidateIssuerSigningKey | トークンを確認するアプリケーションで、トークンの署名に使用されたキーが信頼されていることを保証します キーがトークンに埋め込まれている特殊なケースがあります。 ただし、このケースは通常は発生しません。 |
ValidateLifetime | トークンが引き続きまたは既に有効であることを保証します。 検証コントロールにより、トークンの有効期間が notbefore 要求と expires 要求で指定された範囲内にあるかどうかが確認されます。 |
ValidateSignature | トークンが改ざんされていないことを保証します。 |
ValidateTokenReplay | トークンが再生されていないことを保証します 一部の 1 回限りの使用のプロトコルには特殊なケースがあります。 |
トークンの検証のカスタマイズ
検証コントロールは、TokenValidationParameters クラスのプロパティに関連付けられています。 このプロパティは、ASP.NET と ASP.NET Core の構成から初期化されます。
ほとんどの場合、パラメーターを変更する必要はありません。 シングル テナントではないアプリは例外です。 これらの Web アプリでは、任意の組織から、または個人用 Microsoft アカウントからのユーザーを受け入れます。 この場合、発行者を検証する必要があります。 Microsoft.Identity.Web では発行者の検証も行われます。
ASP.NET Core で、トークン検証パラメーターをカスタマイズする場合は、Startup.cs で次のスニペットを使用します。
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(Configuration);
services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
{
var existingOnTokenValidatedHandler = options.Events.OnTokenValidated;
options.Events.OnTokenValidated = async context =>
{
await existingOnTokenValidatedHandler(context);
// Your code to add extra configuration that will be executed after the current event implementation.
options.TokenValidationParameters.ValidIssuers = new[] { /* list of valid issuers */ };
options.TokenValidationParameters.ValidAudiences = new[] { /* list of valid audiences */};
};
});
ASP.NET MVC の場合、次のコード サンプルにカスタム トークンの検証を行う方法が示されています。
https://github.com/azure-samples/active-directory-dotnet-webapi-manual-jwt-validation
Azure Functions でのトークンの検証
Azure Functions では、受信アクセス トークンを検証することもできます。 このような検証の例については、GitHub の次のコード サンプルを参照してください。
- .NET:Azure-Samples/ms-identity-dotnet-webapi-azurefunctions
- Node.js:Azure-Samples/ms-identity-nodejs-webapi-azurefunctions
- Python: Azure-Samples/ms-identity-python-webapi-azurefunctions)
次のステップ
このシナリオの次の記事である「コードでスコープとアプリのロールを検証する」に進みます。