Custom Authorization in MVC

Introduction

ASP.NET MVC supports various types of Authorization /Authentication that are builtin.

But sometimes we would like to customize it for project requirements.

Before going to the authorization process in depth let's have a look at Authentication and Authorization. Actually there is a bit of a misconception about them.

The following  are the differences in short:

  1. Authentication: It is a process of verification that verifies “Who you are” (it confirms that you are a valid (or invalid) user).
  2. Authorization: It is a process of verification that verifies “What to do” (It confirms you are permissible to do (or not to do) that).

In the MVC framework there are filters that execute in sequence. The sequence is:

  1. Authorization Filters
  2. Action Filters
  3. Result Filters
  4. Exception Filters

It's clear that Authorization filters are taking care of authorizing the current user.

How Authorize Attribute Works

If you are using the ASP.NET membership provider for authentication then it's quite easy to use Authorization in MVC. Here is an example.

  1. [Authorize(Users = "anupam,ashwin")]  
  2. public ActionResult AddArticle()  
  3. {  
  4.    return View();  
  5. }  

We can also specify Roles instead of Users.

Defining Custom Attribute for Authorization

The AuthorizeAttribute Class is defined as:

  1. [AttributeUsageAttribute(AttributeTargets.Class|AttributeTargets.Method, Inherited = true,   
  2. AllowMultiple = true)]  
  3. public class AuthorizeAttribute : FilterAttribute,  
  4. IAuthorizationFilter  
  5. <>{  
  6. public AuthorizeAttribute()  
  7. {…}  
  8. protected virtual bool AuthorizeCore(HttpContextBase httpContext)  
  9. {…}  
  10. public virtual void OnAuthorization(AuthorizationContext filterContext)  
  11. <>{…}  
  12. protected void HandleUnauthorizedRequest(AuthorizationContext filterContext)  
  13. <>{…}  
  14. .  
  15. .  
  16. .  
  17. }   

Note: another method and properties are omitted to keep it simple.

It uses an identity form httpcontext and verifies/validates the user using the AuthorizeCore and OnAuthorization methods.

Implementing Custom Authorization

Now I will put it into practice. I have created a simple CustomAuthorizeAttribute.

A class is derived from the AuthorizeAttribute class (because we need the common behavior of Authentication). I just overrode the 3 base methods CustomAuthorizeAttribute, AuthorizeCore and HandleUnauthorizedRequest.

Here is the code:

  1. public class CustomAuthorizeAttribute : AuthorizeAttribute  
  2. {  
  3.    Entities context = new Entities(); // my entity  
  4.    private readonly string[] allowedroles;  
  5.    public CustomAuthorizeAttribute(params string[] roles)  
  6.    {  
  7.       this.allowedroles = roles;  
  8.    }  
  9.    protected override bool AuthorizeCore(HttpContextBase httpContext)  
  10.    {  
  11.       bool authorize = false;  
  12.       foreach (var role in allowedroles)  
  13.       {  
  14.          var user = context.AppUser.Where(m => m.UserID == GetUser.CurrentUser/* getting user form current context */ && m.Role == role &&  
  15.          m.IsActive == true); // checking active users with allowed roles.  
  16.          if (user.Count() > 0)  
  17.          {  
  18.             authorize = true/* return true if Entity has current user(active) with specific role */  
  19.          }  
  20.       }  
  21.       return authorize;  
  22.    }  
  23.    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)  
  24.    {  
  25.       filterContext.Result = new HttpUnauthorizedResult();  
  26.    }  
  27. }  

I have used comments to describe the behavior.

Uses

This is a simple example and you can customize the behavior depending on your needs. I am just using Role based authentication in this example.

Here is the Action method to demonstrate how to use our CustomAuthorize attribute.

  1. [CustomAuthorize(“Administrator”,”Moderator”)  
  2. public ActionResult AddArticle()  
  3. {  
  4. return View();  
  5. }  

Summary

I hope you have enjoyed it.

I will be looking forward to your valuable feedback/comments.