ASP.NET MVC 4 AllowAnonymous Attribute and Authorize Attribute

ASP.NET MVC 4 AllowAnonymous Attribute and Authorize Attribute

I've been writing a number of ASP.NET MVC 4 Tutorials on new features as I either come across them or use them. One of the new features in ASP.NET MVC 4 is the AllowAnonymous Attribute that helps you secure an entire ASP.NET MVC 4 Website or Controller while providing a convenient means of allowing anonymous users access to certain controller actions, like the login and register Actions. If you look at the AccountController in a default ASP.NET MVC 4 Internet Project you will see AllowAnonymous Attributes sprinkled throughout various login and register controller actions for this very reason.

AllowAnonymous Attribute in ASP.NET MVC 4

As mentioned, if you create a new ASP.NET MVC 4 Internet Project in Visual Studio 2010 or Visual Studio 11 and view the AccountController you will notice the generous use of the AllowAnonymous Attribute on various login and register controller actions. Here are a few of those controller actions.

[Authorize]
public class AccountController : Controller {
  [AllowAnonymous]
  public ActionResult Login() {
    // ...
  }

  [AllowAnonymous]
  [HttpPost]
  public JsonResult JsonLogin(LoginModel model, string returnUrl) {
    // ...
  }

  [AllowAnonymous]
  [HttpPost]
  public ActionResult Login(LoginModel model, string returnUrl) {
    // ...
  }

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

  [AllowAnonymous]
  [HttpPost]
  public ActionResult JsonRegister(RegisterModel model) {
    // ...
  }

  [AllowAnonymous]
  [HttpPost]
  public ActionResult Register(RegisterModel model) {
    // ...
  }
}

The idea is pretty simple. The Authorize Attribute on the AccountController in this ASP.NET MVC 4 Application denies anonymous access to every controller action. However, we need to allow anonymous access to the login and register controller actions so we decorate them with the AllowAnonymous Attribute which negates the Authorize Attribute and allows anonymous access.

Securing Entire ASP.NET MVC 4 Website with Global Filters

The AllowAnonymous Attribute even becomes more handy when you want an entire ASP.NET MVC 4 Web Application secured, but again want to allow anonymous access to those login and register pages. In this case, it makes much more sense to use Global Filters to secure the entire website as opposed to using the Authorize Attribute on a controller-by-controller basis. Alter the RegisterGlobalFilters Method in Global.asax to add an Authorize Attribute to the entire ASP.NET MVC 4 Website.

RegisterGlobalFilters(GlobalFilterCollection filters) {
  filters.Add(new HandleErrorAttribute());
  filters.Add(new System.Web.Mvc.AuthorizeAttribute());
}

You need to specify System.Web.Mvc with the Authorize Attribute because you will find an AuthorizeAttribute in System.Web.Http, too. This now secures every controller action in the entire ASP.NET MVC 4 Website except for those that use the AllowAnonymous Attribute.

Authorize Attribute and OnAuthorization Method

I was curious as to how the AllowAnonymous Attribute in ASP.NET MVC 4 was able to bypass the Authorize Attribute, and the answer is in the Authorize Attribute's OnAuthorization Method. The OnAuthorization Method of the Authorize Attribute looks for an AllowAnonymous Attribute on the action or the controller and bypasses authorization if this is the case.

Here is a snippet of the OnAuthorization Method:

if (!filterContext.ActionDescriptor.IsDefined
    (typeof(AllowAnonymousAttribute), inherit) &&
  !filterContext.ActionDescriptor.ControllerDescriptor.IsDefined
    (typeof(AllowAnonymousAttribute), true)) {
      // Check for authorization
}

Essentially skip authorization if you find an AllowAnonymous Attribute on the action or controller.

Conclusion

Always fun to learn about the new features in ASP.NET MVC 4. You can check out my other ASP.NET MVC 4 Tutorials as well!