September 2, 2015

Granular Level User and Role Management Using ASP.NET Identity

Managing users and roles in the ASP.NET identity framework is a tricky affair, but it can be made easier with the right step-by-step guide. Below is an example of a small use case to illustrate the effectiveness of the ASP.NET Identity framework.

This example will follow ABC Times, a fictitious newspaper that is developing their digital platform in MVC 5 and will implement an identity framework using ASP.NET Identity 2.2.

The key requirements for identity management are that the system should provide authentication of the users and that the system should provide a very flexible way to authorize users.

For the implementation of ASP.NET Identity management, we will refer to this blog on roles-based authorization. However, we will be adding flexibility around authorization in our example.

To build the case, we will assume the following roles:

  • Writer: create, update, read, and delete articles
  • Reviewer: read and approve articles
  • Publisher: publish articles

On the MVC controller side, we have a single ArticleController with the following action methods:

  • Create
  • Read
  • Update
  • Delete
  • Review
  • Approve
  • Publish

After following the first four parts of the blog, the initial implementation of role based security in ASP.NET Identity should be completed.

However, there are a few flexibility concerns that arise:

  • Concern 1: What if a new role is added into the system and it needs to have access to all of the action methods?
  • Concern 2: What if the system needs to prevent a particular writer from deleting an article?

The first concern can be managed by breaking down the roles into a more granular level, so instead of broad category of roles we can define granular level roles as:

  • ArticleCreator
  • ArticleReader
  • ArticleModifier
  • ArticleRemover
  • ArticleReviewer
  • ArticleApprover
  • ArticlePublisher

This allows users to be assigned access to an almost individual level of methods. However, this configuration would be extremely difficult for an administrator to manage because there would be so many users in so many roles. This difficulty brings about a third concern:

  • Concern 3: How can the user in charge of managing the association of granular roles to individual users actually manage it?

To solve this third concern, we must introduce GroupRoles. The earlier broader roles will now collate these granular roles and users will be attached to these GroupRoles instead of the broader Roles.

Below is a mock-up of the system-wide access:

Role Writer Reviewer Publisher
ArticleCreator Allowed
ArticleReader Allowed Allowed
ArticleModifier Allowed
ArticleRemover Allowed
ArticleReviewer Allowed
ArticleApprover Allowed
ArticlePublisher Allowed

Another example of a good implementation of these processes is available here.

To help with the second concern—how to restrict a user who belongs to the write GroupRole from removing articles—we'll reference the fifth part of the blog from above and handle the flexibility concerns through Claims.

Claims can be applied on top of GroupRoles to an individual user. So if we wanted to prevent the writer John from deleting articles, we would create a claim in the system with the name “DenyArticleRemover” and attach it to him.

While creating the ClaimSet, we can also reset the ArticleRemover role to “deny” if an individual user has a “DenyArticleRemover” Claim as well. This step will happen during the creation of a claimset for an individual user. This will then prevent John from removing articles, but not any of the other users.

The system-wide access will then look like this:

Role John (within the Group "Writer") with the claim ClaimType:"DenyArticleRemover" ClaimValue:"True" Other Users within the Group "Writer"
ArticleCreator Allowed Allowed
ArticleReader Allowed Allowed
ArticleModifier Allowed Allowed
ArticleRemover Not Allowed Allowed


Tweaking the ASP.NET Identity Framework in these ways has many advantages for creating a flexible identity system.

Addressing our first concern brought about these benefits:

  • A new role can be easily added into the system
  • Roles can be grouped under a GroupRole
  • When a new user is added and assigned to a GroupRole, all the roles in the group will be automatically attached to that user, meaning that the admin does not have to make code changes every time a user needs new access

Addressing the second concern then allowed admin to add a new claim directly to a user, meaning that they could explicitly remove a user’s particular function by introducing “Deny Claim.”

Addressing the third concern created a model in which admin could manage GroupRoles without having to manage individual granular roles for each individual user, thus cutting down on the number of formulas to keep track of.