Claims-based authorization decides whether a user may perform an action by checking information associated with that user. Authentication answers who made the request; authorization answers whether the requested action is allowed. In ASP.NET Core, the current user is a ClaimsPrincipal containing claims. Each claim has a type and an optional value, such as an email address or an indication of access. section 23.1.1 section 24.1
Think of an airport
Showing a passport establishes who you are. Later, a boarding pass lets you pass security, while a frequent-flyer card may let you enter a lounge. Each checkpoint asks for evidence relevant to that particular action; proving your identity alone does not grant every kind of access. section 24.1
In an app, put the requirements for an endpoint in a named authorization policy. A policy can require a claim to exist or require it to have a particular value. Apply the policy with [Authorize("CanEnterSecurity")] on a Razor Page; the authorization middleware checks the current user's claims before the page executes. section 24.3
Listing 24.4 Adding an authorization policy using AuthorizationPolicyBuilder
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthorizationBuilder() #1
.AddPolicy( #2
"CanEnterSecurity", #3
policyBuilder => policyBuilder #4
.RequireClaim("BoardingPassNumber")); #4
});
// Additional configuration
This configuration adds the CanEnterSecurity policy and requires a BoardingPassNumber claim. The check is for the claim's presence; a policy can instead specify an accepted value. section 24.3
A protected Razor Page has three possible outcomes:
- The user meets the policy: the page executes. section 24.3
- The user is unauthenticated: they are redirected to the login page. section 24.3
- The user is authenticated but lacks the required claims: they are redirected to an access-denied page. section 24.3
The same policy approach applies to minimal API endpoints, where RequireAuthorization("CanCreate") can name a policy. A claim check is not always enough: when permission depends on a particular resource, such as whether a user created a recipe, fetch that resource and authorize against it before changing it. section 25.6
