Custom Authorization with .Net MVC

Hello Its been a while since i wrote any thing technical, so i would like to share today how to add role based custom authorization to .NET MVC project, and the reason for that because it is rarely the case that you stick with .net membership provide and you would like  to have your own provider so here we go

first we need to create Custom Role Provider  class that implements some of the needed functionality that we are concerned about

using backend.DAL;
using System;
using System.Linq;
using System.Web.Security;

namespace backend.Repository
{
	public class CustomedRoleProvider : RoleProvider
	{
		private DatabaseContext db = new DatabaseContext();

		public override void AddUsersToRoles(string[] usernames, string[] roleNames)
		{
			throw new NotImplementedException();
		}

		public override string ApplicationName
		{
			get
			{
				throw new NotImplementedException();
			}
			set
			{
				throw new NotImplementedException();
			}
		}

		public override void CreateRole(string roleName)
		{
			throw new NotImplementedException();
		}

		public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
		{
			throw new NotImplementedException();
		}

		public override string[] FindUsersInRole(string roleName, string usernameToMatch)
		{
			throw new NotImplementedException();
		}

		public override string[] GetAllRoles()
		{
			throw new NotImplementedException();
		}

		public override string[] GetRolesForUser(string email)
		{
			var userObject = db.UsersRoles.FirstOrDefault(user => user.email == email);

			if (userObject == null) 
			{
				string[] emptyRoles = { };
				return emptyRoles;
			}
			else
			{
				string[] result = { userObject.role.roleName };
				return result;
			}
		}

		public override string[] GetUsersInRole(string roleName)
		{
			throw new NotImplementedException();
		}

		public override bool IsUserInRole(string email, string roleName)
		{
			var userObject = db.UsersRoles.FirstOrDefault(user => user.email == email && user.role.roleName == roleName);

			if (userObject == null) { return false; }
			else { return true; }
		}

		public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
		{
			throw new NotImplementedException();
		}

		public override bool RoleExists(string roleName)
		{
			throw new NotImplementedException();
		}
	}
}

then we need to add new class that implements AuthorizeAttribute to be able to decorate our controller functions with the designated role that is allowed to consume such function and to handle authorized and unauthorized requests

using System.Web.Mvc;

namespace backend.Repository
{
    public class CustomAuthorization : AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            if (this.AuthorizeCore(filterContext.HttpContext))
            {
                base.OnAuthorization(filterContext);
            }
            else
            {
                this.HandleUnauthorizedRequest(filterContext);
            }
        }

        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
            {
                base.HandleUnauthorizedRequest(filterContext);
            }
            else
            {
                filterContext.Result = new ViewResult { ViewName = "Unauthorized" };
                filterContext.HttpContext.Response.StatusCode = 403;
            }
        }

    }//end-class

}

Then we implement ActionFilterAttribute to add a setter and getter for our roles

using System.Web.Mvc;

namespace backend.Repository
{
    public class RoleFilterAttribute : ActionFilterAttribute
    {
        public string Role { get; set; }


        [HandleError(View="Shared/Error")]
        public override void OnActionExecuting(ActionExecutingContext ctx)
        {
            var user = ctx.HttpContext.User;

            if (!user.IsInRole(Role))
            {
                ctx.Result = new HttpUnauthorizedResult();
            }
        }
    }
}

Last but not least configure roleManager in web.conf to use our CutomRoleProvider under system.web

<roleManager enabled="true" defaultProvider="CustomRoleProvider">
  <providers>
	<clear />
	<add name="CustomRoleProvider" type="CorporateContact_backend.Repository.CustomedRoleProvider" />
  </providers>
</roleManager>

finally we code decorate our controller functions with who is authorized to consume that designated function for instance. to allow administrator role

  [CustomAuthorization(Roles = "administrator")]

i hope that you will find it for a good use.

pushd /shareShare on Google+0Share on LinkedIn11Tweet about this on TwitterShare on Reddit1Share on Facebook1Email this to someonePrint this page
Posted in Programming and tagged , , , , . Bookmark the permalink. RSS feed for this post. Leave a trackback.

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.

Swedish Greys - a WordPress theme from Nordic Themepark.