Implementing custom policies in ASP.NET Core using the HttpContext

This article shows how to implement a custom ASP.NET Core policy using the AuthorizationHandler class. The handler validates, that the identity from the HttpContext has the authorization to update the object in the database.

Code: https://github.com/damienbod/AspNetCoreAngularSignalRSecurity

Scenerio

In the example, each admin user of the client application, can create DataEventRecord entities which can only be accessed by the corresponding identity. If a different identity with a different user sends a PUT request to update the object, a 401 response is returned. Because the Username from the identity is saved in the database for each entity, the custom policy can validate the identity and the entity to be updated.

Creating the Requirement for the Policy

A simple requirement is created for the policy implementation. The AuthorizationHandler implementation requires this and the requirement class is also used to add the policy to the application.

using Microsoft.AspNetCore.Authorization;

namespace ApiServer.Policies
{
    public class CorrectUserRequirement : IAuthorizationRequirement
    {
        public class CorrectUserRequirement : IAuthorizationRequirement{}
    }
}

Creating the custom Handler for the Policy

If a method is called, which is protected by the CorrectUserHandler, the HandleRequirementAsync is executed. In this method, the id of the object to be updated is extracted from the url path. The id is then used to select the Username from the database, which is then compared to the Username from the HttpContext identity name. If the values are not equal, no success message is returned.

using ApiServer.Repositories;
using Microsoft.AspNetCore.Authorization;
using System;
using System.Threading.Tasks;

namespace ApiServer.Policies 
{
    public class CorrectUserHandler : AuthorizationHandler<CorrectUserRequirement>
    {
        private readonly IDataEventRecordRepository _dataEventRecordRepository;

        public CorrectUserHandler(IDataEventRecordRepository dataEventRecordRepository)
        {
            _dataEventRecordRepository = dataEventRecordRepository;
        }

        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CorrectUserRequirement requirement)
        {
            if (context == null)
                throw new ArgumentNullException(nameof(context));
            if (requirement == null)
                throw new ArgumentNullException(nameof(requirement));

            var authFilterCtx = (Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext)context.Resource;
            var httpContext = authFilterCtx.HttpContext;
            var pathData = httpContext.Request.Path.Value.Split("/");
            long id = long.Parse(pathData[pathData.Length -1]);

            var username = _dataEventRecordRepository.GetUsername(id);
            if (username == httpContext.User.Identity.Name)
            {
                context.Succeed(requirement);
            }

            return Task.CompletedTask;
        }
    }
}

Adding the policy to the application

The custom policy is added to the ASP.NET Core application using the AddAuthorization extension using the requirement.

services.AddAuthorization(options =>
{
	...
	options.AddPolicy("correctUser", policyCorrectUser =>
	{
		policyCorrectUser.Requirements.Add(new CorrectUserRequirement());
	});
});

Using the policy in the ASP.NET Core controller

The PUT method uses the correctUser policy to authorize the request.

[Authorize("dataEventRecordsAdmin")]
[Authorize("correctUser")]
[HttpPut("{id}")]
public IActionResult Put(long id, [FromBody]DataEventRecordDto dataEventRecordDto)
{
	_dataEventRecordRepository.Put(id, dataEventRecordDto);
	return NoContent();
}

If a user logs in, and tries to update an entity belonging to a different user, the request is rejected.

Links:

https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies

Advertisements

5 comments

  1. […] Implementing custom policies in ASP.NET Core using the HttpContext – Damien Bowden […]

  2. […] Implementing custom policies in ASP.NET Core using the HttpContext (Damien Bowden) […]

  3. […] L’implémentation de Custom Policies dans ASP.NET Core en utilisant HttpContext. […]

    1. Hi Cristovao

      This is for ASP.NET Core 2.0

      Greetings Damien

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: