Understanding ASP.NET MVC Filters

What is filter?

Filters are custom classes or piece of codes that provide both a declarative and programmatic, means to add some logic before and after action method to controller action methods.

Why filters needed

We need to perform logic before an action method executes or after an action method runs.To support this, ASP.NET MVC provides filters.

Types of Filters

The ASP.NET MVC framework provides five types of filters.

  1. Authentication filters (New in ASP.NET MVC5)
  2. Authorization filters
  3. Action filters
  4. Result filters
  5. Exception filter

Authentication filters

Authentication filters set an authentication scheme for individual controllers or actions. The IAuthenticationFilter interface is used to create CustomAuthentication filter. See interface definition below-

public interface IAuthenticationFilter
{
void OnAuthentication(AuthenticationContext filterContext);
void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext);
}

Examples of Authentication filter:

We want our Controller or action method available for user that have Admin or SuperAdmin role.

public class AdminSuperAdminAttribute : FilterAttribute, IAuthenticationFilter
    {
        string superAdminRole = "SuperAdmin"; // can be taken from resource file or config file
        string adminRole = "Admin"; // can be taken from resource file or config file
        public void OnAuthentication(AuthenticationContext context)
        {
            if (context.HttpContext.User.Identity.IsAuthenticated &&
            (context.HttpContext.User.IsInRole(superAdminRole)
            || context.HttpContext.User.IsInRole(adminRole)))
            {
                // do nothing
            }
            else
            {
                context.Result = new HttpUnauthorizedResult(); // mark unauthorized
            }
        }
        public void OnAuthenticationChallenge(AuthenticationChallengeContext context)
        {
            if (context.Result == null || context.Result is HttpUnauthorizedResult)
            {
                context.Result = new RedirectToRouteResult("Default",
                new System.Web.Routing.RouteValueDictionary{
                {"controller", "Account"},
                {"action", "Login"},
                {"returnUrl", context.HttpContext.Request.RawUrl}
                });
            }
        }
    }

In the above code, we are doing following steps:

  • Step 1: We have inherited this class file with FilterAttribute and IAuthenitcaitonFilter interface.
  • Step 2: We have taken two variables and hard coded the role names.
  • Step 3: Interface IAuthenitcaitonFilter force us to implement two methods named OnAuthentication and OnAuthenticationChallenge.
  • Step 4: In OnAuthentication method, we have checked user is authenticated and role is superadmin or admin.
  • Step 5: If does nothing else set the context.Result to HttpUnathorizedResult (unauthorized).
  • Step 6: The same is being checked inside OnAuthenticationChallenge method and if it is null or HttpUnauthorizedResult then user is being redirected to the Login page of the website with current url as returnUrl querystring.

Inject authentication filter at controller level

[AdminSuperAdmin]
public class AdminSuperAdminController : Controller
{
}

Inject authentication filter at action level

[AdminSuperAdmin]
public ActionResult Create()
{
return View();
}

Authorization filters

Authorization filters are taking care of authorizing the current user. Authorization filters enforce your authorization policy, ensuring that action methods can be invoked only by approved users. Authorization filters implement the IAuthorizationFilter interface.See interface definition below-

public interface IAuthorizationFilter
{
void OnAuthorization(AuthorizationContext filterContext);
}

The “AuthorizeAttribute” class already implements the “IAuthorizationFilter” interface and when we create a custom class from the “AuthorizeAttribute” class we need to override the following methods:

public class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter
{
protected virtual bool AuthorizeCore(HttpContextBase httpContext);
protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext);
public virtual void OnAuthorization(AuthorizationContext filterContext);
protected virtual HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext);
}

How Authorize Attribute filter Works

If we are using the ASP.NET membership provider for authentication then it’s quite easy to use Authorization in MVC. Here is an example.

[Authorize(Users = "arkroop,akash")]
public ActionResult AddArticle()
{
 return View();
}

We can also specify Roles instead of Users. Defining Custom Attribute for Authorization

Implementing Custom Authorization

When we create a custom authorization filter, there are 2 ways:

  • Implements the “IAuthorizationFilter” interface
  • Derive from the “AuthorizeAttribute” class

In most cases, we are going to create a filter by deriving from the “AuthorizeAttribute” class.

	public class BlackListAuthAttribute : AuthorizeAttribute
    {
        private string[] disAllowedUsers;

        public BlackListAuthAttribute(params string[] disAllowedUsers)
        {
            this.disAllowedUsers = disAllowedUsers;
        }

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            bool isAuthenticated = httpContext.Request.IsAuthenticated;
            bool isInBlackList = disAllowedUsers.Contains(httpContext.User.Identity.Name, StringComparer.InvariantCultureIgnoreCase);
            return isAuthenticated && !isInBlackList;
        }
    }
  • Step 1: We have inherited this class file with AuthorizeAttribute class.
  • Step 2: We have taken string type array for add disallow users list.
  • Step 3: Override the “AuthorizeCore()” method
  • Step 4: In AuthorizeCore method, we have checked user is authenticated and role is not black listed user.
  • Step 5: Override the “HandleUnauthorizedRequest()” method it is Optional.

Now you can apply the filter to a controller or an action method.

[BlackListAuth("Raj", "Amar")]
public ActionResult Index()
{
  return View();
}

Action filters

Action filter is responsible for performing additional logic before and after the action execution. The IActionFilter interface is used to create an Action Filter. See interface definition below-

public interface IActionFilter
{
void OnActionExecuting(ActionExecutingContext filterContext);
void OnActionExecuted(ActionExecutedContext filterContext);
}

An action filter is implemented as an attribute class that inherits from ActionFilterAttribute we need to override the following methods:

public class ActionAttribute : ActionFilterAttribute
{
public virtual void OnActionExecuting(ActionExecutingContext filterContext);
public virtual void OnActionExecuted(ActionExecutedContext filterContext);
}

To implement an action filter, you must override at least one of these methods.

Implementing Custom Action filter

Below shows a simple action filter that logs trace messages before and after an action method is called

public class LoggingFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            filterContext.HttpContext.Trace.Write("(Logging Filter)Action Executing: " +
            filterContext.ActionDescriptor.ActionName);
            base.OnActionExecuting(filterContext);
        }
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            if (filterContext.Exception != null)
                filterContext.HttpContext.Trace.Write("(Logging Filter)Exception thrown");
            base.OnActionExecuted(filterContext);
        }
    }

Result filters

Result filters are pretty much similar to action filters, except they run after the action method has executed, but before the result returned from the action method has been executed. The “before” method is called OnResultExecuting and the “after” method is called OnResultExecuted. See interface definition below-

public interface IResultFilter
{
void OnResultExecuted(ResultExecutedContext filterContext);
void OnResultExecuting(ResultExecutingContext filterContext);
}

Exception filters

The exception filters are all guaranteed to run after all of the action filters and result filters have run. Even if an exception filter indicates that it can handle the exception, it will still run.The exception filters implements the interface IExceptionFilter. See interface definition below-

public interface IExceptionFilter
{
void OnException(ExceptionContext filterContext);
}

Ordering filters

The order of a filter in which it run depends upon the type of the filter, the scope at which it applied and the value of the Order property. Regarding the types of filters, the Authorization filters runs at first and the Exception filters runs at last.

customfilterimg1

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>