Search code examples
c#.netasp.net-mvcsecuritycross-cutting-concerns

Applying non-MVC related attributes to MVC actions


Our application has the notion of a PermissionAttribute. This attribute is defined in a base layer of our application and our commands and queries are decorated with that attribute. Since this attribute is defined in base layer we can't (and don't want to) to let it inherit from FilterAttribute or implement System.Web.Mvc.IActionFilter on it.

Still we would like to apply this attribute to controller actions as follows:

[Permission(Permissions.Administration.ManageUsers)]
public ActionResult Index()
{
    return this.View();
}

Based on this attribute the proper security checks should be applied. I've been browsing through the MVC code base to find the proper hooks to customize MVCs behavior to allow adding these security checks based on this custom attribute. I though about creating a custom ControllerActionInvoker that returned a custom ReflectedControllerDescriptor from its GetControllerDescriptor method, which would return FilterAttribute that would be created based on the existence of the PermissionAttribute, but it feels like a lot of work, and I'm not sure this is the correct path to walk.

What would be am efficient and pleasant way to customize the MVC pipeline so that we can handle this non-MVC related attribute?


Solution

  • I would do it this way. First create your own implementation of the AuthorizeAttribtues like this:

    public class PermissionAuthoriseAttribute : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            //Leaving the implementation of this to you, but you check if your
            //PermissionAttribute is assigned and call it's methods.
            if(...)
                return true;
    
            //You may want to check this first, depending on your requirements
            return base.AuthorizeCore(httpContext);
        }
    }
    

    Then apply this across your project by adding this line to the FilterConfig.cs file:

    filters.Add(new PermissionAuthoriseAttribute());