views:

600

answers:

4

Hello,

I made a new action filter (attribute, similar to [Authorize]) which authorizes access to a controller action based on a session value. However, I'm basically decorating all my controller actions with that attribute (with the exception of very few).

So, I thought it would be better to have that Action Filter always executed except in cases where I attach an [ExemptFromAuthorize] attribute to a controller action? (Maybe via inheriting to my own Controller class?)

How can I do this?

+1  A: 

You can add the attribute to the class to have it apply to all methods in that class

[Authenticate]
public class AccountController : Controller
{
    public ActionResult Index()
    {
  return View();
    }
}

I don't know how to exclude a specific method from a class-level attribute. Maybe use a separate controller for unauthenticated requests?

John Sheehan
Making separate controllers would spaghetti-ize my code ... excluding specific methods from the class level attribute would be exactly what I need.
Alex
+2  A: 

Maybe try and add an Except property to your first attribute?

[MyAuthenticate(Exempt="View")]
public class MyController : Controller
{
    public ActionResult Edit()
    {
        // Protected
    }

    public ActionResult View()
    {
        // Accessible by all
    }
}
jeef3
How would the logic in the action filter work though? (Actually making the "Exempt" work)?
Alex
+3  A: 

Running with jeef3's answer, I came up with this. It could use more error checking and robustness like multiple delimited actions, but the general idea works.

In your specific case, you could test for the session value and decide to return out of the authorization also.

public class AuthorizeWithExemptionsAttribute : AuthorizeAttribute
{
    public string Exemption { get; set; }
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        if (filterContext.RouteData.GetRequiredString("action") == Exemption)
            return;

        base.OnAuthorization(filterContext);
    }

}

Usage:

[AuthorizeWithExemptions(Roles="admin", ExemptAction="Index")]
public class AdminController : Controller
...
Ben Robbins
A: 

Check out my article on codeproject -

http://www.codeproject.com/KB/web-security/AuthorizeWithExemptions.aspx

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.

snipper from the code:

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);
}
Maxim