liveBook · Manning

Imperative authorization

As explained in ASP.NET Core in Action, 3e

Imperative authorization is an authorization approach in which application code explicitly invokes authorization logic during endpoint execution.

Imperative authorization lets application code decide whether an operation may continue by explicitly calling authorization logic. It is useful when authorization depends on a resource that must be loaded first, such as a recipe the current user wants to edit. section 24.5.1 section 24.4.2

A typical resource-based authorization flow is:

  • Inject IAuthorizationService into the endpoint or service. section 24.5.1
  • Load the resource before making the authorization decision. section 24.5.1 section 24.4.2
  • Call AuthorizeAsync with the ClaimsPrincipal user, resource, and policy name. section 24.5.1
  • Continue when AuthorizationResult.Succeeded is true; otherwise return ForbidResult. section 24.5.1

Editing a recipe

An Edit Razor Page retrieves a Recipe, evaluates the CanManageRecipe policy against User and that recipe, then blocks execution when authorization fails. Traditional web apps may redirect to an access-denied page, while API apps typically return HTTP 403. section 24.5.1

Listing 24.14 Using IAuthorizationService for resource-based authorization
[Authorize]                                                       #1
public class EditModel : PageModel
{
    [BindProperty]
    public Recipe Recipe { get; set; }
 
    private readonly RecipeService _service;
    private readonly IAuthorizationService _authService;          #2
 
    public EditModel(
        RecipeService service,
        IAuthorizationService authService)                        #2
    {
        _service = service;
        _authService = authService;                               #2
    }
 
    public async Task<IActionResult> OnGet(int id)
    {
        Recipe = _service.GetRecipe(id);                          #3
        AuthorizationResult authResult = await _authService       #4
            .AuthorizeAsync(User, Recipe, "CanManageRecipe");     #4
        if (!authResult.Succeeded)                                #5
        {                                                         #5
            return new ForbidResult();                            #5
        }                                                         #5
 
        return Page();                                            #6
    }
}

Inspect the annotated Razor Page listing showing dependency injection, resource loading, AuthorizeAsync, and the failed-authorization branch. section 24.5.1

How ASP.NET Core in Action, 3e covers it

How deep it goes
Explains injection, resource loading, policy evaluation, success checking, and forbidden responses through a working Razor Page example.
Examples
Uses recipe editing, the Recipe resource, the CanManageRecipe policy, AuthorizeAsync, and ForbidResult.
What it assumes
Assumes familiarity with [Authorize], authorization policies, ClaimsPrincipal, and loading an application resource.
What you can do after
Apply it via IAuthorizationService to authorize a loaded resource before allowing endpoint work to continue.
How it connects
Connects imperative authorization with declarative authorization, resource-based authorization, authorization policies, claims, and Razor Pages.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of ASP.NET Core in Action, 3e. The section links point to the parts of the book it draws on.