Security authorization
.NET Core ASP.NET Core C# Dependency Injection OAuth Patterns Visual Studio Web API

How to use a Declarative Authorization Policy to Secure Web API Application Resources

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.

Social media & sharing icons powered by UltimatelySocial