LoginSignup
0
1

More than 1 year has passed since last update.

ASP.NET Core でPolicyベースの認可でOR判定したいとき

Posted at

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/

元ネタ参考ソース:
https://github.com/tekTutorialsHub/Authorization-in-ASP-NET-Core/tree/main/04.%20Policy%20based%20Authorization/AuthzExample

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1