I'm not sure how to implement combined "OR" requirements in ASP.NET Core Authorization. In previous versions of ASP.NET this would have been done with roles, but I'm trying to do this with claims, partly to understand it better.
Users have an enum called AccountType that will provide different levels of access to controllers/actions/etc. There are three levels of types, call them User, BiggerUser, and BiggestUser. So BiggestUser has access to everything the account types below them have and so on. I want to implement this via the Authorize tag using Policies.
So first I have a requirement:
public class TypeRequirement : IAuthorizationRequirement
{
public TypeRequirement(AccountTypes account)
{
Account = account;
}
public AccountTypes Account { get; }
}
I create the policy:
services.AddAuthorization(options =>
{
options.AddPolicy("UserRights", policy =>
policy.AddRequirements(new TypeRequirement(AccountTypes.User));
});
The generalized handler:
public class TypeHandler : AuthorizationHandler<TypeRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, TypeRequirement requirement)
{
if (!context.User.HasClaim(c => c.Type == "AccountTypes"))
{
context.Fail();
}
string claimValue = context.User.FindFirst(c => c.Type == "AccountTypes").Value;
AccountTypes claimAsType = (AccountTypes)Enum.Parse(typeof(AccountTypes), claimValue);
if (claimAsType == requirement.Account)
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}
What I would to do is add multiple requirements to the policy whereby any of them could satisfy it. But my current understanding is if I do something like:
options.AddPolicy("UserRights", policy => policy.AddRequirements(
new TypeRequirement(AccountTypes.User),
new TypeRequirement(AccountTypes.BiggerUser)
);
Both requirements would have to be satisfied. My handler would work if there was someway in AddRequirements to specify an OR condition. So am I on the right track or is there a different way to implement this that makes more sense?