Click here to Skip to main content
16,017,502 members
Articles / Web Development / ASP.NET

ASP.NET MVC - AuthorizeWithExemptionsAttribute

Rate me:
Please Sign up or sign in to vote.
4.57/5 (5 votes)
26 Aug 2010CPOL2 min read 34K   475   16   4
This base controller will secure all your actions except those which will be marked as UnsecuredAction.

Introduction

In this article, I'll provide you with a solution for securing ASP.NET MVC application's controllers in a way that all the actions are secured except those you define as unsecure (by default, all the actions are unsecure unless you define them as secure).

I encountered a problem in the ASP.NET MVC authorization model, which is built as opt-in. You can secure an action or a controller using the [Authorize] attribute. The problem is that if you want to secure a whole controller and make some actions in that controller as not secured - you can't.

This article will explain to you how you can secure a whole controller and make some actions as not secured within it.

This project was written in Visual Studio 2010 as an ASP.NET MVC 2 project.

Background

I was looking for a solution to that problem, and couldn't find a reasonable one. Other solutions suggested to:

  • Move the unsecured actions to another controller (not secured)
  • Write the AuthorizeCore method to be dependent on the Action's names
  • Put the [Authorize] attribute on all the actions except the non-secured actions

In this article, I'll provide you with my solution to this problem.

Using the Code

To use the code, you'll need your controllers to put any [CustomAuthorize] attribute which inherits from AuthorizeWithExemptionsAttribute on your controllers. Calling any action on this controller will include an authorization check. If you want to mark an Action as non-secured, just put the [UnsecuredAction] Attribute above it.

Explanation

The core of this solution is in the [AuthorizeWithExemptions] Attribute in the OnAuthorization method. This method checks if the called Action has the UnsecuredActionAttribute, and if it does, it marks filterContext.HttpContext.SkipAuthorization as true.

C#
public override void OnAuthorization(AuthorizationContext filterContext)
{
    ActionDescriptor action = filterContext.ActionDescriptor;
    bool IsUnsecured = action.GetCustomAttributes(
                         typeof(UnsecuredActionAttribute), true).Count() > 0;

    //If doesn't have UnsecuredActionAttribute - then do the authorization
    filterContext.HttpContext.SkipAuthorization = IsUnsecured;

    base.OnAuthorization(filterContext);
}

Then, CustomAuthorizeAttribute performs the authorization check only if SkipAuthorization is false.

C#
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
  if (httpContext.SkipAuthorization)
  {
      return true;
  }

  // Do any authorization logic here
  return httpContext.Request.QueryString["password"] == "password";
}

* Of course, never provide the password in the QueryString, it was made like that just for the ease of the example.

So now, when you try to invoke the secured controller, you get the HTTP error code 401: Unauthorized.

Image 1

And the unsecured controller works without any authorization required.

Image 2

History

  • 23rd August, 2010: Initial post
  • 24th August, 2010: Updated article and source code

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Team Leader Leverate
Israel Israel
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionAllowAnonymous Pin
Maddy_100831-Jul-15 2:44
Maddy_100831-Jul-15 2:44 
GeneralDrop the inheritance requirement Pin
paul.vencill23-Aug-10 18:05
paul.vencill23-Aug-10 18:05 
GeneralRe: Drop the inheritance requirement Pin
sakrank23-Aug-10 18:12
sakrank23-Aug-10 18:12 
GeneralRe: Drop the inheritance requirement Pin
Maxim Novak24-Aug-10 9:58
Maxim Novak24-Aug-10 9:58 
Thanks! You're right.

I started writing it on ASP.NET MVC1, there you can't get the ActionDescription in the Onauhtorize method.

I re-factored the article and re-submitted it. The new version will be up soon.

M@x.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.