ASP.NET MVC 4.0 Custom Authorize Attribute

DaveI was working on an MVC 4.0 web application that contained some WebAPI controllers.  The requirement was to secure the site using Windows Authentication.  However, only the web pages required security but, the Api controllers did not. I changed the web.config and IIS 7.5 to provide Windows Authentication.  I then added an authorize attribute to my MVC controllers like “[Authorize(Roles = “FooWebUsers”)]”.  Since, the WebAPI controllers did not need security I added the [AllowAnonymous] attribute to those controllers.

I tested the site and discovered the MVC Controllers were properly secured, prompting a login – ok good. Hit one of the API routes in fiddler and got a NT challenge and response or prompt for Login. What’s going on here?  I added [AllowAnonymous] to the API controllers – not working.  After much digging around I found what I wanted by implementing a custom Authorization attribute. Here’s the steps I went through to implement this.

In order to  implement Windows Authentication you will need to change the authentication mode in the sites Web.config file to “Windows” like below:

<system.web>
    <compilation debug="false" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
    <authentication mode="Windows" />

Next, IIS 7.5 requires a few changes as well. Within IIS Manager, click your site then in the right pane click the “Authentication” icon located in the “IIS” section.  Set “Windows Authentication” to Enabled and set “Anonymous Authentication” to Enabled.  Here’s what the authentication should look like:

IIS_7.5config

Now, you have IIS and the web.config setup the rest of this post will explain the various pieces of code to be implemented.

  1. First create a class that inherits from AuthorizeAttribute.
  2. Then override the OnAuthorization method.
 public class ApiAuthorizeSkip : AuthorizeAttribute 
 {
        public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            if (!(actionContext.ControllerContext.Controller is APIController1 ||
                  actionContext.ControllerContext.Controller is APIController2))
                  base.OnAuthorization(actionContext);
        }
     }
  }

You can add a wide range of custom logic in this method, check users in role, whether a controller inherits from foobase Controller etc..

Next, you will need to modify the Global.asax file making it aware that your app is to use this new custom authorization.  Add code shown below to the Application_OnStart():

protected void Application_Start()
{
            AutoMapperConfiguration.Configure();
            var container = ObjectFactory.Container;
            AreaRegistration.RegisterAllAreas();
            GlobalConfiguration.Configuration.Filters.Add(new ApiAuthorizeSkip());
            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
}

Notice: The class name provided to the Filters.Add method in the highlighted code above matches the name of the custom authorization class I created.

Finally, ensure that your controllers not requiring security are decorated with the [AllowAnonymous] attribute and the controllers you want secured to have something like [Authorize(Roles = “FooRoles”)]. In my case, I added the [AllowAnonymous] attribute to my Api controller base class.
In order to test to determine if things are working put a break point on the “Application_Start()” method then recycle your websites app pool so it will run the Application_Start() again.  Then, put a break point on the OnAuthorization() method added to the ApiAuthorizationSkip class. Now, open Fiddler, click the composer tab  and enter a URL like: ”https://abcdefg.com/ServiceApi/method/01062” that routes to a controller you want to test.  In both cases you should see the code in the Global.asax and the custom OnAuthorization() method class being executed.
I created two base controller classes one for MVC Controllers and, one for Api controllers. That way I could specify intended behavior in one place.

One thought on “ASP.NET MVC 4.0 Custom Authorize Attribute

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s