July 20th, 2016

ASP.NET Core Identity and Role based Security

In previous post, we created enum for different roles and added them in database on application startup. In this post, we will implement role based security.
It uses following environment:


ASP.NET Core 1.0.1
Postgresql 9.5.4 database
Dapper 1.50.2
Visual Studio 2015 update 3
Identity.Dapper

Add User to Role:

Before implementing security, we need to add user to a role. We can do it just after creating user in Register post action by using AddToRoleAsync method of UserManager like below:

 var result = await _userManager.CreateAsync(user, model.Password);
 await _userManager.AddToRoleAsync(user, Roles.Tester.ToString());

Here is Roles enum:

 public enum Roles
    {
        Administrator,
        Editor,
        User,
	    Tester
    }

Role Based Authorization:

Here is the traditional way to check roles

        [Authorize(Roles = "Administrator")]
        public IActionResult Administration()
        {
           ViewData["Message"] = "This is Administration area." ;
           return View();
        }

        [Authorize(Roles = "Administrator,Editor")]
        public IActionResult Review()
        {
            ViewData["Message"] = "This is Moderation panel";                       
            return View();
        }

Review action would be only accessible by users who are members of either Administrator or Editor role.
To use enum instead of text and to handle multiple roles, the simple solution is to create custom authorizeattribute, use the params keyword in your constructor and do the needed operations as shown here. But it is old fashion.

Policy Based Authorization:

The new Policy syntax is more dynamic. It is registered in ConfigureServices in the Startup.cs file:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
 services.AddAuthorization(options =>
            {
                options.AddPolicy("AdminOnly", policy => policy.RequireRole(Roles.Administrator.ToString()));
                options.AddPolicy("Moderator", policy => policy.RequireRole(Roles.Administrator.ToString(),Roles.Editor.ToString()));
            });

Policies are applied using the Authorize attribute by specifying the policy name:

 [Authorize(Policy = "AdminOnly")]    
        public IActionResult Administration()
        {           
            ViewData["Message"] = "This is Administration area." ;
            return View();
        }

      [Authorize(Policy = "Moderator")]
        public IActionResult Review()
        {
            ViewData["Message"] = "This is Moderation panel";                                                                                       
            return View();
        }

It has the same behaviour as done in traditional way. But it is easy to modify any policy rule and it will be applied automatically on all associated controllers/actions.

You can see more details of policy based implementation on docs

Conclusion:

In this post, we have seen how to add user to role, traditional approach to implement role based security and the new way policy based authorization in ASP.NET Core.
Hope it helps.