views:

86

answers:

2

How to enable Authentication on whole controller and disable only for certain action methods. I want authentication for all resources. If I write something like that:

[Authorize]
public class HomeController : BaseController
{
    //This is public
    [UnAuthorized]
    public ActionResult Index()
    {
        ViewData["Message"] = "Welcome to ASP.NET MVC!";
        return View();
    }
    //This is private resource
    public ActionResult PrivateResource()
    {
        return View();
    }
}

Then anyone can access this resource. I need this because we have all resources is private and very few is public on our project. Do you have any ideas how to make it better way?

+2  A: 

Organize your controllers accordingly. Have a base controller for all authenticated resources which you could annotate with the [Authorize] attribute and another one for public resources.

[Authorize]
public abstract BaseAuthenticatedController : Controller
{ }

public abstract BaseController : Controller
{ }
Darin Dimitrov
Thank you Darin. It is not what I wanted exactly. I want to be able to make certain action methods of controller to be public and rest of them private.
Tim
+1  A: 

Based on solution which is found here I wrote the code that fixes exactly what I wanted.

Create custom authorization attribute base on AuthorizeAttribute and override method OnAuthorization:

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        if (filterContext != null)
        {
            object[] attributes = filterContext.ActionDescriptor.GetCustomAttributes(false);
            if (attributes != null)
            {
                foreach (var attribute in attributes)
                    if (attribute is UnAuthorizedAttribute)
                        return;
            }
        }
        base.OnAuthorization(filterContext);
    }

I'm using a reflection here to recognize an action with UnAuthorized attribute. I don't know about performance issues in this case, but it solves the problem completely.

Tim
Much of this code is unnecessary. Just use ActionDescriptor.GetCustomAttributes() directly, so you can bypass using reflection to guess what the incoming method is.
Levi
Thank you Levi! I edited my post according your comment
Tim