• Skip to primary navigation
  • Skip to main content

Feras' Blog

Enjoy your journey

  • Home
  • About Me
  • Cloud Scenarios
  • العربية

How To Verify Roles From Db With Authorization Handler ASP.NET CORE 2.2

If you are building a solution that supports roles based authorization in ASP.NET CORE 2.2, most probably you are using ASP.NET Identity.

September 3, 2019 By فراس طالب

If you are building a solution that supports roles based authorization in ASP.NET CORE 2.2, most probably you are using ASP.NET Identity.

You secure each action method with [Authorize] attribute and you set the roles according to the business logic you have.

In this blog post, I will explain how to create a custom authorization handler to verify user’s roles from the database.

This the scenario that we want to solve:

  • A user logged in to the system
  • The system generated claims that contain roles assigned to the user. e.g ( John has (Role1, Role2)
  • Claims will be embedded in a cookie or an access token based on the authentication scheme.
  • The admin user updated the unassigned the Role2 from John. which mean the cookie or the access token has the wrong claims.
  • John is still logged in to the system, the secure cookie contains two claims (Role1, Role2) and he is still able to access the system according to claims in the cookie.

The reason is that the default behavior of Authorization will compare the required roles of [Authorize(Role=“Role2“)] to claims coming with the user’s request (inside a secured cookie or inside an access token) based on the authentication scheme the user has.

To solve this problem, you can implement your own Authorization Handler in ASP.NET CORE and inject it in the DI container.

To do that you need two steps :

1- Create a new implementation of IAuthorizationHandler

In my case, I inherited from AuthorizationHandler class that implements IAuthorizationHandler.

The parent class support passing generic Requirement class. I want to validate based on Roles so there is already a RolesAuthorizationRequirement class for that purpose.

public class RolesInDBAuthorizationHandler : AuthorizationHandler<RolesAuthorizationRequirement>, IAuthorizationHandler
    {
        private readonly ApplicationDbContext _dbContext;


        public RolesInDBAuthorizationHandler(ApplicationDbContext identityTenantDbContext)
        {
            _dbContext = identityTenantDbContext;
        }

        protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context,
                                                       RolesAuthorizationRequirement requirement)
        {
            if (context.User == null || !context.User.Identity.IsAuthenticated)
            {
                context.Fail();
                return;
            }

            var found = false;
            if (requirement.AllowedRoles == null ||
                requirement.AllowedRoles.Any() == false)
            {
                // it means any logged in user is allowed to access the resource
                found = true;
            }
            else
            {

                var userId = context.User.GetUserId();
                var roles = requirement.AllowedRoles;
                var roleIds = await _dbContext.Roles
                                                    .Where(p => roles.Contains(p.Name))
                                                    .Select(p => p.Id)
                                                    .ToListAsync();

                found = await _dbContext.UserRoles
                                        .Where(p => roleIds.Contains(p.RoleId) && p.UserId == userId)
                                        .AnyAsync();
            }

            if (found)
            {
                context.Succeed(requirement);
            }
            else
            {
                context.Fail();
            }
        }
    }

2- Add The New Authorization Handler To DI Container

what we will do is injecting a new IAuthorizationHandler implementation that verifies roles from Db.

In startup.cs, add the following code to ConfigureServices

services.AddTransient<IAuthorizationHandler, RolesInDBAuthorizationHandler>();

ASP.NET core supports roles-based and claims-based authorizations. both models use a requirement. requirement handler and a preconfigured policy.

so you can also check Policy-based authorization to get more info about ASP.NET Core authorization models.

Performance Challenge

After implementing the solution, there will be an extra query that hits the database in each HTTP request to validate the user’s access.

To avoid this you can cache the user’s permission in a Redis memory cache. but you have to update the memory cache whenever the admin updates the user’s roles.

Conclusion!

How to create a custom authorization handler in ASP.NET Core 2.2?

You implement IAuthorizationHandler then you inject the class in ConfigureServices in the startup.cs file

Filed Under: Software Development Tagged With: .NET Core, ASP.NET Core, ASP.NET Identity

Topics

  • Agile
  • Digital Marketing
  • General
  • Scrum
  • Software Architecture
  • Software Development

Copyright © 2025 Feras' Blog