ASP.NET Core でRoleベースの認可でOR判定したいときは、以下のようにロールをカンマ区切りで指定すればよい。
[Authorize(Roles = "HRManager,Finance")]
public class SalaryController : Controller
{
public IActionResult Payslip() =>
Content("HRManager || Finance");
}
じゃあ、Policyベースの認可でOR判定したいときはどうすればよいのか。
同じように実施するとエラーになる。
[Authorize(Policy = "BadgeEntry,TemporarySticker")]
//InvalidOperationException: The AuthorizationPolicy named: 'BadgeEntry,TemporarySticker' was not found.
public IActionResult VacationBalance()
{
return View();
}
Requirementを同じHandlerを複数作ってそのHandlerをDIコンテナに登録すれば、それがOR条件になる。
using Microsoft.AspNetCore.Authorization;
using AuthorizationPoliciesSample.Policies.Requirements;
public class BuildingEntryRequirement : IAuthorizationRequirement { }
public class BadgeEntryHandler : AuthorizationHandler<BuildingEntryRequirement>
{
protected override Task HandleRequirementAsync(
AuthorizationHandlerContext context, BuildingEntryRequirement requirement)
{
if (context.User.HasClaim(
c => c.Type == "BadgeId" && c.Issuer == "https://microsoftsecurity"))
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}
public class TemporaryStickerHandler : AuthorizationHandler<BuildingEntryRequirement>
{
protected override Task HandleRequirementAsync(
AuthorizationHandlerContext context, BuildingEntryRequirement requirement)
{
if (context.User.HasClaim(
c => c.Type == "TemporaryBadgeId" && c.Issuer == "https://microsoftsecurity"))
{
// Code to check expiration date omitted for brevity.
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}
builder.Services.AddSingleton<IAuthorizationHandler, BadgeEntryHandler>();
builder.Services.AddSingleton<IAuthorizationHandler, TemporaryStickerHandler>();
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("BadgeEntry,TemporarySticker", policy =>
policy.Requirements.Add(new BuildingEntryRequirement));
});
元ネタ:
https://learn.microsoft.com/ja-jp/aspnet/core/security/authorization/policies?view=aspnetcore-6.0#why-would-i-want-multiple-handlers-for-a-requirement
https://www.tektutorialshub.com/asp-net-core/policy-based-authorization-in-asp-net-core/