Search
Close this search box.

Implementing a custom ASP.NET MVC authorization filter

Technorati Tags: .NET,ASP.NET,ASP.NET MVC

I’m rewriting a “classic ASP” (that term always makes me laugh – Just ’cause it’s old don’t make it “classic”) application in ASP.NET MVC 2. There’s an existing user authorization table in the database, so I want to keep using that for authorization determination.

I created a custom class inheriting from FilterAttribute and implementing IAuthorizationFilter:

1:  public class DuffAuthorizeAttribute : FilterAttribute, IAuthorizationFilter
   2:  {
   3:      public DuffAuthorizeAttribute(params UserRole[] acceptedRoles)
   4:      {
   5:          _acceptedRoles = acceptedRoles;   
   6:      }
   7:   
   8:      public void OnAuthorization(AuthorizationContext filterContext)
   9:      {
  10:          User currentUser = UserHelper.GetCurrentUser();
  11:   
  12:          if (!currentUser.IsInRole(_acceptedRoles))
  13:              throw new DuffUnauthorizedAccessException();
  14:      }
  15:   
  16:      private readonly UserRole[] _acceptedRoles;
  17:   
  18:      private IUserHelper _userHelper;
  19:      public IUserHelper UserHelper
  20:      {
  21:          get
  22:          {
  23:              if (_userHelper == null)
  24:                  _userHelper = ObjectFactory.Create<UserHelper>();
  25:   
  26:              return _userHelper;
  27:          }
  28:          set { _userHelper = value; }
  29:      }
  30:  }

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:

1:  public class AdministrationController : Controller
   2:  {
   3:      [DuffAuthorize(UserRole.Administrator)]
   4:      public virtual ActionResult AdministerUsers()
   5:      {
   6:          return View();
   7:      }
   8:   
   9:      [DuffAuthorize(UserRole.Administrator, /*or*/ UserRole.AdminAssistant)]
  10:      public virtual ActionResult Reports()
  11:      {
  12:          return View();
  13:      }
  14:  }

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.

Thursday, July 08, 2010 9:54 PM

This article is part of the GWB Archives. Original Author: Brian Schoer

Related Posts