Editar: Desde ASP.NET MVC 4, el mejor enfoque es simplemente usar el atributo AllowAnonymous incorporado .
La respuesta a continuación se refiere a versiones anteriores de ASP.NET MVC
Puede crear un atributo de autorización personalizado heredado del AuthorizeAttribute estándar con un parámetro bool opcional para especificar si la autorización es necesaria o no.
public class OptionalAuthorizeAttribute : AuthorizeAttribute
{
private readonly bool _authorize;
public OptionalAuthorizeAttribute()
{
_authorize = true;
}
public OptionalAuthorizeAttribute(bool authorize)
{
_authorize = authorize;
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if(!_authorize)
return true;
return base.AuthorizeCore(httpContext);
}
}
Entonces puedes decorar tu controlador base con ese atributo:
[OptionalAuthorize]
public class ControllerBase : Controller
{
}
y para cualquier controlador que no desee autorización, simplemente use la anulación con un 'falso', por ejemplo
[OptionalAuthorize(false)]
public class TestController : ControllerBase
{
public ActionResult Index()
{
return View();
}
}
[AllowAnonymous]
atributo.Parece que ASP.NET MVC 4 'solucionó' esto agregando un atributo AllowAnonymous .
David Hayden escribió sobre esto :
[Authorize] public class AccountController : Controller { [AllowAnonymous] public ActionResult Login() { // ... } // ... }
fuente
Mi opinión personal sobre esto sería dividir el controlador. Simplemente cree otro controlador. Para las acciones, no necesita autenticación.
O podrías tener:
BaseController
no requiere autenticación - aquí tienes todas tus "cosas básicas" :).
BaseAuthController : BaseController
todas las acciones aquí requieren autenticación.
De esa manera, puede tener autenticación cuando lo desee, simplemente derivando de una clase específica.
fuente
Si solo desea que una acción no esté autorizada en un controlador autorizado, puede hacer algo como esto:
public class RequiresAuthorizationAttribute : ActionFilterAttribute { private readonly bool _authorize; public RequiresAuthorizationAttribute() { _authorize = true; } public RequiresAuthorizationAttribute(bool authorize) { _authorize = authorize; } public override void OnActionExecuting(ActionExecutingContext filterContext) { var overridingAttributes = filterContext.ActionDescriptor.GetCustomAttributes(typeof (RequiresAuthorizationAttribute), false); if (overridingAttributes.Length > 0 && overridingAttributes[0] as RequiresAuthorizationAttribute != null && !((RequiresAuthorizationAttribute)overridingAttributes[0])._authorize) return; if (_authorize) { //redirect if not authenticated if (!filterContext.HttpContext.User.Identity.IsAuthenticated) { //use the current url for the redirect var redirectOnSuccess = filterContext.HttpContext.Request.Url.AbsolutePath; //send them off to the login page //var redirectUrl = string.Format("?RedirectUrl={0}", redirectOnSuccess); var loginUrl = LinkBuilder.BuildUrlFromExpression<HomeController>(filterContext.RequestContext, RouteTable.Routes, x => x.Login(redirectOnSuccess)); filterContext.HttpContext.Response.Redirect(loginUrl, true); } } } }
fuente