Welcome to today’s post.
Declarative authorization allows authorization of resources to be checked before a controller action method is accessed. The implementation of the authorization rule can be built around policies and requirements, which when satisfied, allow access to the resource.
In a previous post we discussed imperative authorization, which allows authorization of resources to be embedded as code within the logic of controllers or views to allow more fine-grained access to the controller resource. With imperative authorization we can use the IAuthorizationService and execute a custom authorization method.
Authorization policies consist of one or many requirements. The requirements can consist of CRUD requirements, or rule-based requirements, such as user age-based, or financial based restriction.
Let us look at an example of declarative policy-based authorization.
In this example we can allow any user that is authenticated to view books.
Step 1 – Implement an authorization handler
Below is our authorization handler:
namespace BookLoan.Authorization
{
public class BookReadAccessHandler : IAuthorizationHandler
{
public Task HandleAsync(AuthorizationHandlerContext context)
{
var user = context.User;
var pendingRequirements = context.PendingRequirements.ToList();
foreach (var requirement in pendingRequirements)
{
if (requirement == BookLoanOperations.Read)
{
if (user.Identity.IsAuthenticated)
{
context.Succeed(requirement);
}
}
}
return Task.CompletedTask;
}
}
}
Step 2 – Setup the authorization policies
In Startup.cs include the namespace:
using Microsoft.AspNetCore.Authorization;
In ConfigureServices() we add the authorization policies and handlers:
// Authorization policies
services.AddAuthorization(options =>
{
options.AddPolicy("BookReadAccess", policy =>
{
policy.AddRequirements(
BookLoanOperations.Read);
});
options.AddPolicy("BookUpdateAccess", policy =>
{
policy.AddRequirements(
BookLoanOperations.Update);
});
options.AddPolicy("BookCreateAccess", policy =>
{
policy.AddRequirements(
BookLoanOperations.Create);
});
});
// Authorization handlers.
services.AddSingleton<IAuthorizationHandler,
BookAccessHandler>();
services.AddSingleton<IAuthorizationHandler,
BookUpdateAccessHandler>();
services.AddSingleton<IAuthorizationHandler,
BookCreateAccessHandler>();
When the application enters the route for \Edit or \Detail\{i}, the handlers above will be executed.
Step 3 – Declare the authorization policy
We decorate the controller action with the authorize attribute and the policy as shown with an Edit method:
// GET: Book/Edit/5
[Route("Edit/{id}")]
[Authorize(Policy = "BookUpdateAccess")]
public async Task<ActionResult> Edit(int id)
{
…
}
When the code in the authorization handler:
context.Succeed(requirement);
is executed, then the controller action code block will be executed, else the application will redirect over to the action Account\AccessDenied.
That’s all for today.
I hope this has been a useful post on how to secure your controllers using policy based authorizations.
You can refer to our previous post on imperative authorization for an alternative approach.

Andrew Halil is a blogger, author and software developer with expertise of many areas in the information technology industry including full-stack web and native cloud based development, test driven development and Devops.