Monday, September 21, 2015

Custom Authorize using AuthorizeAttribute

Requirement: Once authenticated, a user should be authorized using his/her role to access certain modules of my application.

Assuming you already have a login page and users are being validated against DB. Please read Custom Authentication using IAuthenticationFilter

Step 1: Create a folder named "CustomAttributes" in the root of your MVC website.

Step 2: Create a class named "CustomUserAuthorizationAttribute" under the newly created folder.

Step 3: Inherit and implement the class using AuthorizeAttribute

public class CustomUserAuthorizationAttribute : AuthorizeAttribute
{
 //Implemention goes here
}

Step 4: Use following Namespaces:

using System.Web.Mvc;
using System.Web.Mvc.Filters;

Step 5: Create members shown below:

     /// <summary>
        /// List of roles allowed. This will be passed in the attribute declarartion
        /// </summary>
        private readonly string[] RolesAllowed;


        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="roles">The roles.</param>
        public CustomUserAuthorizationAttribute(params string[] roles)
        {
            this.RolesAllowed = roles;
        }


        /// <summary>
        /// This is called when a controller/Action decorated with [CustomUserAuthorization] is executed
        /// </summary>
        /// <param name="httpContext">The HTTP context.</param>
        /// <returns></returns>
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            //This holds the authorization token in form of a boolean
            bool authorize = false;

            //Get User info from Session
            var currentUserSessionInfo = Common.GetFromSession<UserSessionInfo>(Common.SessionKeys.UserSessionInfo);
            
            //Read all the roles passed in RolesAllowed from attribute declaration on a Controller/Action
            foreach (var role in RolesAllowed)
            {
                //If User is null OR User Role is NULL, set authorize token to false
                if (currentUserSessionInfo == null || currentUserSessionInfo.Role == null)
                {
                    authorize = false;
                }
                //match user's role, if match is found; set the authorize token to true 
                else if (currentUserSessionInfo.Role.Equals(role, StringComparison.OrdinalIgnoreCase))
                {
                    authorize = true;
                }
            }
            return authorize;
        }



        /// <summary>
        /// This is triggered after AuthorizeCore has returned autorize token. You may redirect to a specific page
        /// </summary>
        /// <param name="filterContext">The filter context.</param>
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            filterContext.Result = new HttpUnauthorizedResult();
            //Redirect to a specific page to let user know that he/she is not authorized to view the page or take action.
        }

Step 6: Now decorate an action with [CustomUserAuthorization].

I wanted to allow only authenticated users to access my home page, my controller looked like this:

[CustomUserAuthorization("Admin", "SuperAdmin")]
public ActionResult DeleteUser()
{
    //Implemention goes here
}

Every time DeleteUser action is called, user is authorized to see if he/she is belongs to Admin or SuperAdmin role. You may simply decorate new actions with specified roles.

No comments:

Post a Comment