Using Custom Action Filters in Class Libraries

21 Aug 2013 .Net, C#, Filters, MVC 2 Comments

I have recently been creating a class library that many MVC web applications are going to reference, and I wanted those applications to be able to implement some custom Action Filters so they did not need to duplicate code. I had originally thought this was not possible, due to the different applications needing redirection to their respective controllers and actions, but once I discovered how easy it was to pass in variables to an Action Filter, or to access predefined attributes in the individual web applications’ respective web.config files I realised it would not be too difficult to implement these Action Filters.

Please see my previous post if you want more information on Passing Variables to Custom Action Filters.

Must Have Role Example

One of the action filters I wished to implement was an authorisation attribute, which could be used to mark individual controllers or individual actions as only accessible to users with certain roles. Here I will show an example of the attribute restricting access to a whole controller. MyClassLibrary is referenced by MyWebProject.

MyWebProject Controller

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

namespace MyWebProject.Controllers
{
    [MustHaveRole(Role="admin")]
    public class AdminController : BaseController
    {
        public ActionResult Index()
        {
            return View();
        }
    }
}

MyClassLibrary Action Filter

using System.Web.Mvc;
using System.Web.Routing;
using System.Configuration;

namespace MyClassLibrary.Filters
{
    public class MustHaveRoleAttribute : ActionFilterAttribute
    {
        public string Role {get; set;}

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            // Get currently logged in user
            // Check if user has a role using string Role
            // Redirect if user does not have the specified role
            if(!hasRole)
            {
                string c = ConfigurationManager.AppSettings["UnauthController"].ToString();
                string a = ConfigurationManager.AppSettings["UnauthAction"].ToString();
                filterContext.Result = new RedirectToRouteResult(
		    new RouteValueDictionary
		    {
			{ "controller", string.IsNullOrEmpty(c) ? "Home" : c }, 
			{ "action", string.IsNullOrEmpty(a) ? "Index" : a }
		    }
		);
            }
        {
    }
}

If the user does not have the specified role (is not authorised) they are redirected to an ‘unauthorised’ controller and action. These are specified in the web application’s web.config file or are set to defaults of Home and Index if there is a problem with retrieving those values. The specified action may just be a view which tells the user they are not authorised to access that area, but it is up to the developer of each web app to decide that.