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>();
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)
- one handler for multiple requirements
- policy has multiple requirements
- handler has logic to handle multiple requirements
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