Patrick Desjardins Blog
Patrick Desjardins picture from a conference

Make all actions of controller securized with Authorise filter implicit

Posted on: 2012-08-09

Few months ago, I had to Asp.Net membership to an Asp.Net Mvc project. Instead of adding the filter [Authorize] on every action that require to have a valid authentification I decided to use the technic describe in this MSDN Blog.

The main goal is by inverting the normal behavior of the security, which is to mark with a filter which method to protect, is to mark the one that shouldn't be protected. That mean that by default, everything is secured. By default, everything require an authenticated user. So, with this new filter, only anonymous method require to have the filter.

How do we implement that? First, we need to add a new filter that will authorize only method that contain a specific filter. This is done by adding 3 line of code in the Global.asax.cs.

public static void RegisterGlobalFilters(GlobalFilterCollection filters) { 
   filters.Add(new LogonAuthorize()); 
} 

Since version 3 of ASP.NET MVC, you can add the AuthorizeAttribute filter to the global.asax file to protect every action method of every controller. Second, we need to create the LogonAuthorize class that inherit from AuthorizeAttribute.

 public sealed class LogonAuthorize : AuthorizeAttribute { 
  public override void OnAuthorization(AuthorizationContext filterContext) { 
    bool skipAuthorization = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) || filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true); 
    if (!skipAuthorization) { 
      base.OnAuthorization(filterContext); 
    } 
  } 
} 

If the base.OnAuthorization() is skip, than we do not have any protection. If the base.OnAuthorization() is called, than the protection mechanism is called and authentification rules are applied.

So, what's happen in the OnAuthorization method? It simply check if the method or the class contain the attribute defined (AllowAnonymous). If it does, than we skip the authorization so we do not call the base class AuthorizeAttribute.

From there, you need to add [AllowAnonymous] to methods that you want to be allowed without having the visitor authenticated. For example, method for login and creating an account should have this attribute.

[AllowAnonymous] public ActionResult LogOn() { 
  //... 
}