Search in Help for developer site.

Thursday 2 November 2017

Roles based authorization attribute in Controller or Action level in ASP.NET MVC

Overview :

Modern web development has many challenges, and of those security is both very important and often under-emphasized.

The modern software developer has to be something of a Swiss army knife. Of course, you need to write code that fulfills customer functional requirements. It needs to be fast. Further you are expected to write this code to be comprehensible and extensible, sufficiently flexible to allow for the evolutionary nature of IT demands, but stable and reliable.

Somewhere, way down at the bottom of the list of requirements, behind, fast, cheap, and flexible is “secure”. That is, until something goes wrong, until the system you build is compromised, then suddenly security is, and always was, the most important thing.

As when 'web security' word comes into the discussion, I just would like to brief out about Authorization and Authentication concepts before heading towards my article..

1. What is Authentication?


Authentication is any process by which you verify that someone is who they claim they are. This usually involves a username and a password, but can include any other method of demonstrating identity, such as a smart card, retina scan, voice recognition, or fingerprints. Authentication is equivalent to showing your drivers license at the ticket counter at the airport.

2. What is Authorization?


Authorization is finding out if the person, once identified, is permitted to have the resource. This is usually determined by finding out if that person is a part of a particular group, if that person has paid admission, or has a particular level of security clearance. Authorization is equivalent to checking the guest list at an exclusive party, or checking for your ticket when you go to the opera.

Well, without wasting time we shall get into the topic. So.., as far as security is concerned, today I am going to show you all how to implement "Role based authorization".

Scenario :

Let's assume that we have one MVC application which has various web screens.So,
here I want users who use this app should be able to access the specific screen once they are fully authorized to use it based on their roles. To enable this feature in my app, I am going to implement 'roles based authorization'.

Step 1 : Create MVC app and name it something like 'BookStore'.

Step 2 : Add controller and name it as 'Home'. My controller looks something like as below.

    [CustomAuthorizeByRole("Admin")]   //Only admin can access.
    public class HomeController : Controller
    {
        //
        // GET: /Home/
        public ActionResult Index()
        {
            return View();
        }

    }

Allright,as you can see above I have used custom attribute called 'CustomAuthorizeByRole'.Well., let me brief you what it actually does. So, whenever if you want to enable the app user to access only specific controller or action method, you should decorate them using this custom attribute.

As you can see above I am restricting user from being access home page who are not a part of 'Admin' role. In addition, I am able to allow the app users to access the home screen who are part of multiple roles. So to enable this, you just have to write  similar like below:  
 
   [CustomAuthorizeByRole("Admin","Manager","Analyst")]

Look at above line of code, I am restricting users from being access home page who are not part of 'admin' or 'manager' or 'analyst'.


Step 3 : Implement custom role based authorization

 A. Create a class and name it as 'CustomAuthorizeByRole'.

 B. Add below lines of code.





using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.Routing;

namespace CustomAuthorization
{
    public class CustomAuthorizeByRole : AuthorizeAttribute
    {
        private readonly string[] allowedroles;
        public CustomAuthorizeByRole(params string[] roles)
        {
            this.allowedroles = roles;
        }

        private List<string> GetCurrentUserSkills()
        {
            var userSkills = new List<string>();
            userSkills.Add("Admin");
            userSkills.Add("Manager");
            userSkills.Add("ReadOnlyUser");
            //This values can come from database also.
            return userSkills;
        }

        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);
        }
        protected override bool AuthorizeCore(HttpContextBase context)
        {
            bool result = false;
            result = IsUserAuthorized();
            if (result)
                base.AuthorizeCore(context);
            return result;
        }

        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            filterContext.Result = new ViewResult { ViewName = "UnAuthorized" };
        }

        private bool IsUserAuthorized()
        {
            var IsValidUser = false;
            var currentUserRoles = GetCurrentUserSkills();
            foreach (string UserRole in allowedroles)
            {
                IsValidUser = currentUserRoles.Contains(UserRole);
                if (IsValidUser)
                    return IsValidUser;
            }
            return IsValidUser;
        }
    }
} 


As you can see above block of code, my constructor is accepting roles as string array which in turn validate the current user roles accessibility. If any of the roles of current user is containing in  roles string array which is being passed as parameter in constructor method.,  then that user would be able to access the home page.

So for demonstration purpose, I have hard coded the roles for the current user and will use them to check whether or not any of user roles is present in given string array.
And if user roles do not contain in any of the passed roles., then app will take the user to 'UnAuthorize' view, and it would look like below.




Note : Your custom authorize class must inherit 'AuthorizeAttribute'  filter class.

That's it. Now run your application and see the result, it should work.!!!

Thank you.

Please feel free to share your doubts and queries. I will be glad to help you out.


Articles You May Like.


How to create custom code snippets in visual studio





How to generate C# Model Class or Data Object of a Database Table

How to overcome difficulties facing in jquery ajax call and handling it to get proper response from ASP NET MVC Action Method