Is it possible to disable authorization on one action in an MVC controller?
asp.net Mvcasp.net Mvc Problem Overview
I have an authorization attribute on a controller, but I'd like to turn it off on one action. I created my own authorization filter and added "Anonymous" into the Roles list. In my filter I then return true if Anonymous appears in the role list.
However, it doesn't seem to get past the login page as if the controller authorization is pre-empting anything else.
asp.net Mvc Solutions
Solution 1 - asp.net Mvc
You can add [Authorize]
To the controller class, and then add [AllowAnonymous]
to the single action you don't want to be authorized. Example:
[Authorize]
public class AccountController : Controller
{
public ActionResult Profile()
{
return View();
}
[AllowAnonymous]
public ActionResult Login()
{
return View();
}
}
Solution 2 - asp.net Mvc
You can create your own version of the attribute.
There is a very similar question and there is a pretty good answer how to implement your own attribute that handles this situation.
https://stackoverflow.com/questions/746998/override-authorize-attribute-in-asp-net-mvc
Btw. you could also create your controller that would have authorization by default.
Base
[Authorize]
public abstract class SecureControllerBase : Controller
{
}
Usage
public class MyController : SecureControllerBase
{
}
Solution 3 - asp.net Mvc
I just did a solution using Azure ACS as the federated Identity Provider and the accepted answer didn't work for me. For those who are struggling, my solution was to bypass the security altogether for the required controller/views.
Create a new Controller/Views for those actions which you need to bypass the authorization.
And in the web.config add the following ,
<location path="TheNameOfTheControllerYouWantToBypass">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
Solution 4 - asp.net Mvc
Simply add the attribute to the Actions you want to filter, and not on the controller class. By not decorating actions, they will not be filtered, provided the controller or one of its base controllers hasn't got the attribute.
Solution 5 - asp.net Mvc
Do not add AuthorizationAttribute on your action method where ever you do not required for example.
My custom attribute
public class AuthorizationFilterAttribute : AuthorizeAttribute
{
// Some code...
}
My controller
public class UserController : BaseController, IDisposable
{
[AuthorizationFilterAttribute]
public ActionResult UserList()
{
// Authorize attribute will call when this action is executed
}
public ActionResult AddUser()
{
// Authorize attribute will not call when this action is executed
}
}
I hope you got my point what I am trying to say you.
============================ Updated Answer ================================
Create one more attribute like below.
public sealed class AnonymousAttribute : Attribute { }
Please put below code on your OnAuthorization method.
public override void OnAuthorization(AuthorizationContext filterContext)
{
bool checkForAuthorization =
filterContext.ActionDescriptor.IsDefined(typeof(AnonymousAttribute), true) ||
filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AnonymousAttribute), true);
if (!skipAuthorization)
{
base.OnAuthorization(filterContext);
}
}