Skip to content

Authorization

Policy-based Authorization

Background

In ASP.NET Core, policy-based authorization is a flexible way to enforce access control. It involves requirements, handlers, and policies.

under the hood, role-based authorization and claims-based authorization use a requirement and a preconfigured policy

Requirement

resembles an authorization requirement the logic is implemented by a handler(s) the requirement is consumed in a policy

public class MinimumAgeRequirement : IAuthorizationRequirement
{
    public int MinimumAge { get; }
    public MinimumAgeRequirement(int minimumAge) => MinimumAge = minimumAge;
}

Handler

responsible for evaluation logic for requirement(s) the handler is registered in DI

public class MinimumAgeHandler : AuthorizationHandler<MinimumAgeRequirement>
{
    protected override Task HandleRequirementAsync(
        AuthorizationHandlerContext context,
        MinimumAgeRequirement requirement)
    {
        if (context.User.HasClaim(c => c.Type == "Age"))
        {
            int age = int.Parse(context.User.FindFirst(c => c.Type == "Age").Value);
            if (age >= requirement.MinimumAge)
            {
                context.Succeed(requirement);
            }
        }
        return Task.CompletedTask;
    }
}

Policy (Registration)

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("AdultOnly", policy =>
        policy.Requirements.Add(new MinimumAgeRequirement(18)));
});

builder.Services.AddSingleton<IAuthorizationHandler, MinimumAgeHandler>();

Register a handler

Usage

[Authorize(Policy = "AdultOnly")]
public IActionResult RestrictedAccess()
{
    return Ok("You have access!");
}
var authResult = await _authorizationService.AuthorizeAsync(User, null, "AdultOnly");
if (authResult.Succeeded)
{
    // Grant access
}

Use IAuthorizationService, [Authorize(Policy = "Something")], or RequireAuthorization("Something") for authorization.

Mapping

different types are handler -> requirement mapping

One-to-one Authorization

  • [one handler for one requirement](A requirement can have multiple handlers. A handler may inherit AuthorizationHandler, where TRequirement is the requirement to be handled. Alternatively, a handler may implement IAuthorizationHandler directly to handle more than one type of requirement.)

One-to-many Authorization ("AND" Authorization)

Many-to-one Authorization (for "OR" Authorization (chain))

  • many handlers per requirement
  • policy has 1 requirement, but many handlers as options to fulfill the requirement
  • uses public class [Badge/TempBadge]EntryHandler : AuthorizationHandler<BuildingEntryRequirement>
  • multiple handlers requirement
  • register both handlers