IAuthorizationRequirementData インターフェイスを使用して、属性定義で承認ポリシーに関連付けられている要件を指定します。
サンプル アプリ
この記事で説明する完全なサンプルは、 AuthRequirementsData サンプル アプリ (dotnet/AspNetCore.Docs.Samples GitHub リポジトリ) (ダウンロード方法) です。 このサンプル アプリでは、ユーザーの最小年齢ハンドラーが実装され、ユーザーは少なくとも 21 歳であることを示す生年月日要求を提示する必要があります。
最小年齢承認属性
MinimumAgeAuthorizeAttributeのIAuthorizationRequirementData実装では、承認期間が設定されます。
using Microsoft.AspNetCore.Authorization;
namespace AuthRequirementsData.Authorization;
class MinimumAgeAuthorizeAttribute(int age) : AuthorizeAttribute,
IAuthorizationRequirement, IAuthorizationRequirementData
{
public int Age { get; set; } = age;
public IEnumerable<IAuthorizationRequirement> GetRequirements()
{
yield return this;
}
}
最小年齢承認ハンドラー
MinimumAgeAuthorizationHandler クラスは、ジェネリック パラメーター IAuthorizationRequirementで指定された、MinimumAgeAuthorizeAttributeによって提供される単一のMinimumAgeAuthorizeAttributeを処理します。
HandleRequirementAsync メソッド:
- ユーザーの生年月日の主張を取得します。
- 要求からユーザーの年齢を取得します。
- ユーザーが今年誕生日を過ごしていない場合は、年齢を調整します。
- ユーザーが年齢要件を満たしている場合は、承認要件が成功したことをマークします。
- デモンストレーション用のログ記録を実装します。
using System.Globalization;
using System.Security.Claims;
using Microsoft.AspNetCore.Authorization;
namespace AuthRequirementsData.Authorization;
class MinimumAgeAuthorizationHandler(ILogger<MinimumAgeAuthorizationHandler> logger)
: AuthorizationHandler<MinimumAgeAuthorizeAttribute>
{
// Check whether a given minimum age requirement is satisfied.
protected override Task HandleRequirementAsync(
AuthorizationHandlerContext context,
MinimumAgeAuthorizeAttribute requirement)
{
logger.LogInformation(
"Evaluating authorization requirement for age >= {age}",
requirement.Age);
// Get the user's birth date claim.
var dateOfBirthClaim =
context.User.FindFirst(c => c.Type == ClaimTypes.DateOfBirth);
if (dateOfBirthClaim != null)
{
// If the user has a date of birth claim, obtain their age.
var dateOfBirth = Convert.ToDateTime(dateOfBirthClaim.Value,
CultureInfo.InvariantCulture);
var age = DateTime.Now.Year - dateOfBirth.Year;
// Adjust age if the user hasn't had a birthday yet this year.
if (dateOfBirth > DateTime.Now.AddYears(-age))
{
age--;
}
// If the user meets the age requirement, mark the authorization
// requirement succeeded.
if (age >= requirement.Age)
{
logger.LogInformation(
"Minimum age authorization requirement {age} satisfied",
requirement.Age);
context.Succeed(requirement);
}
else
{
logger.LogInformation(
"Current user's DateOfBirth claim ({dateOfBirth}) doesn't " +
"satisfy the minimum age authorization requirement {age}",
dateOfBirthClaim.Value,
requirement.Age);
}
}
else
{
logger.LogInformation("No DateOfBirth claim present");
}
return Task.CompletedTask;
}
}
MinimumAgeAuthorizationHandlerは、アプリのIAuthorizationHandler ファイルにシングルトン Program サービスとして登録されます。
builder.Services.AddSingleton<IAuthorizationHandler,
MinimumAgeAuthorizationHandler>();
GreetingsControllerは、ユーザーが最小年齢ポリシーを満たす場合に、[MinimumAgeAuthorize({AGE})]属性を持つ 21 歳の年齢を使用して、ユーザーの名前を表示します。ここで、{AGE}プレースホルダーは年齢です。
using Microsoft.AspNetCore.Mvc;
using AuthRequirementsData.Authorization;
namespace AuthRequirementsData.Controllers;
[ApiController]
[Route("api/[controller]")]
public class GreetingsController : Controller
{
[MinimumAgeAuthorize(21)]
[HttpGet("hello")]
public string Hello() =>
$"Hello {HttpContext.User.Identity?.Name}!";
}
ユーザーの生年月日要求が 21 歳以上であることを示す場合、コントローラーはあいさつ文字列を表示し、200 (OK) 状態コードを発行します。 ユーザーに生年月日の要求がない場合、または要求が 21 歳以上でないことを示している場合、あいさつは表示されず、403 (禁止) 状態コードが発行されます。
JWT ベアラー認証サービスは、アプリの Program ファイルに追加されます。
builder.Services.AddAuthentication().AddJwtBearer();
アプリ設定ファイル (appsettings.json) は、JWT ベアラー認証の対象ユーザーと発行者を構成します。
"Authentication": {
"Schemes": {
"Bearer": {
"ValidAudiences": [
"https://localhost:51100"
],
"ValidIssuer": "dotnet-user-jwts"
}
}
}
前の例では、localhost 対象ユーザーは、アプリの起動プロファイル (applicationUrl) でProperties/launchSettings.jsonによって指定された localhost アドレスと一致します。
デモ
dotnet user-jwtsと curl を使用してサンプルをテストします。
コマンド シェル内のプロジェクトのフォルダーから、次のコマンドを実行して、21 歳以上のユーザーを作成する生年月日要求を含む JWT ベアラー トークンを作成します。
dotnet user-jwts create --claim http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dateofbirth=1989-01-01
出力では、コマンド シェルの "Token:" の後にトークンが生成されます。
New JWT saved with ID '{JWT ID}'.
Name: {USER}
Custom Claims: [http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dateofbirth=1989-01-01]
Token: {TOKEN}
後で使用するために、トークンの値 (前の出力に {TOKEN} プレースホルダーが表示される場所) を別に設定します。
jwt.msなどのオンライン JWT デコーダーでトークンをデコードしてコンテンツを表示し、ユーザーの生年月日を含むbirthdate要求が含まれていることを明らかにできます。
{
"alg": "HS256",
"typ": "JWT"
}.{
"unique_name": "{USER}",
"sub": "{USER}",
"jti": "{JWT ID}",
"birthdate": "1989-01-01",
"aud": [
"https://localhost:51100",
"http://localhost:51101"
],
"nbf": 1747315312,
"exp": 1755264112,
"iat": 1747315313,
"iss": "dotnet-user-jwts"
}.[Signature]
21 歳未満のユーザーを作成する dateofbirth 値を指定して、コマンドをもう一度実行します。
dotnet user-jwts create --claim http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dateofbirth=2020-01-01
2 番目のトークンの値を確保しておく。
Visual Studio で、または .NET CLI の dotnet watch コマンドを使用してアプリを起動します。
.NET CLI で、次の curl.exe コマンドを実行して、 api/greetings/hello エンドポイントを要求します。
{TOKEN} プレースホルダーを、前に保存した最初の JWT ベアラー トークンに置き換えます。
curl.exe -i -H "Authorization: Bearer {TOKEN}" https://localhost:51100/api/greetings/hello
ユーザーの生年月日要求が 21 歳以上であることを示しているため、出力は成功を示します。
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Date: Thu, 15 May 2025 22:58:10 GMT
Server: Kestrel
Transfer-Encoding: chunked
Hello {USER}!
ログは、年齢要件が満たされたことを示します。
MinimumAgeAuthorizationHandler: Information: Evaluating authorization requirement for age >= 21
MinimumAgeAuthorizationHandler: Information: Minimum age authorization requirement 21 satisfied
ユーザーが 21 歳未満であることを示す 2 番目のトークンを使用して、 curl.exe コマンドを再実行します。 出力は、要件が満たされていないことを示します。 エンドポイントへのアクセスは禁止されています (状態コード 403):
HTTP/1.1 403 Forbidden
Content-Length: 0
Date: Thu, 15 May 2025 22:58:36 GMT
Server: Kestrel
MinimumAgeAuthorizationHandler: Information: Evaluating authorization requirement for age >= 21
MinimumAgeAuthorizationHandler: Information: Current user's DateOfBirth claim (2020-01-01) doesn't satisfy the minimum age authorization requirement 21
ASP.NET Core