What's up!

Pyaarey Allah!

Friday, February 25, 2011

Implementing a custom ASP.NET MVC authorization filter

I created a custom class inheriting from FilterAttribute and implementing

IAuthorizationFilter:
     public class CustAuthorizeAttribute : FilterAttribute, IAuthorizationFilter
     {
         public CustAuthorizeAttribute(params UserRole[] acceptedRoles)
         {
             _acceptedRoles = acceptedRoles;   
         }
      
         public void OnAuthorization(AuthorizationContext filterContext)
         {
            User currentUser = UserHelper.GetCurrentUser();
     
            if (!currentUser.IsInRole(_acceptedRoles))
                throw new CustUnauthorizedAccessException();
      }
     
        private readonly UserRole[] _acceptedRoles;
     
        private IUserHelper _userHelper;
        public IUserHelper UserHelper
        {
            get
            {
                if (_userHelper == null)
                    _userHelper = ObjectFactory.Create();
     
                return _userHelper;
            }
            set { _userHelper = value; }
        }
    }
My constructor takes a params list of one or more UserRole enumeration values. IAuthorizationFilter only has one method that must be implemented: OnAuthorization. In my implementation, I'm checking whether the current user is in one of the roles supplied to the constructor. (My User.IsInRole method also takes a params list of accepted roles.) (I wish I could set my IUserHelper implementation via constructor injection instead of having to resolve it from my IOC container within the attribute class, but I don't think that's possible, since .NET attribute constructor syntax doesn't it.) Adding authorization for a controller action is as easy as applying the attribute to an action (or it could be applied at the class level to be in effect for all of the controller's actions:
 public class AdministrationController : Controller
     {
         [CustAuthorize(UserRole.Administrator)]
         public virtual ActionResult AdministerUsers()
         {
             return View();
         }
      
         [CustAuthorize(UserRole.Administrator, /*or*/ UserRole.AdminAssistant)]
        public virtual ActionResult Reports()
        {
            return View();
        }
    }

In the example above, only users with an "Administrator" role are authorized for the "AdministerUsers" view, and users with either an "Administrator" or "AdminAssistant" role can see the "Reports" view. If users without the required roles try to go to those views, an exception will be thrown.

0 comments: (+add yours?)

Post a Comment