¿Puede habilitar [Autorizar] para el controlador pero deshabilitarlo para una sola acción?

StackOverflow https://stackoverflow.com/questions/329500

  •  11-07-2019
  •  | 
  •  

Pregunta

Me gustaría usar [Autorizar] para cada acción en mi controlador de administración, excepto la acción Iniciar sesión .

[Authorize (Roles = "Administrator")]
public class AdminController : Controller
{
    // what can I place here to disable authorize?
    public ActionResult Login()
    {
        return View();
    }
}
¿Fue útil?

Solución

No creo que pueda hacer esto con el atributo Authorize estándar, pero podría derivar su propio atributo de AuthorizeAttribute que toma una lista de acciones para permitir y permite el acceso solo a esas acciones. Puede consultar la fuente de AuthorizeAttribute en www.codeplex.com para obtener ideas sobre cómo hacer esto. Si lo hizo, podría verse así:

[AdminAuthorize (Roles = "Administrator", Exempt = "Login, Logout") ]
public class AdminController : Controller
{
    public ActionResult Login()
    {
        return View();
    }

    public ActionResult Login()
    {
        return View();
    }

    ... other, restricted actions ...
}

EDITAR : Para su información, eventualmente me encontré con la necesidad de hacer algo similar por mi cuenta y tomé una dirección diferente. Creé un proveedor de filtro de autorización predeterminado y aplico un filtro de autorización global. El proveedor del filtro de autorización utiliza la reflexión para verificar si una acción o controlador tiene un atributo de autorización específico aplicado y, de ser así, difiere. De lo contrario, aplica un filtro de autorización predeterminado. Esto se combina con un PublicAttribute derivado de AuthorizeAttribute que permite el acceso público. Ahora, obtengo acceso seguro predeterminado, pero puedo otorgar acceso público a través de [Public] aplicado a una acción o controlador. Una autorización más específica también se puede aplicar según sea necesario. Vea mi blog en http: // farm-fresh -code.blogspot.com/2011/04/default-authorization-filter-provider.html

Otros consejos

Puede decorar su controlador con [Autorizar] y luego puede decorar el método que desea eximir con [AllowAnonymous]

Puede anular el método OnAuthorization del controlador

    protected override void OnAuthorization(AuthorizationContext filterContext)
    {
        if ((string)(filterContext.RouteData.Values["action"]) == "Login")
        {
            filterContext.Cancel = true;
            filterContext.Result = Login();
        }
    }

Esto funciona pero es un truco.

Código de clase completo utilizado para probar:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;

namespace MvcApplication2.Controllers
{
[HandleError]
[Authorize]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewData["Title"] = "Home Page";
        ViewData["Message"] = "Welcome to ASP.NET MVC!";

        return View();
    }


    public ActionResult About()
    {
        ViewData["Title"] = "About Page";

        return View();
    }


    protected override void OnAuthorization(AuthorizationContext filterContext)
    {
        if ((string)(filterContext.RouteData.Values["action"]) == "Index")
        {
            filterContext.Cancel = true;
            filterContext.Result = Index();
        }
    }
}
}

Puede que no sea real, pero escribí mi atributo personalizado:

public class SelectableAuthorizeAttribute : AuthorizeAttribute
{
    public SelectableAuthorizeAttribute(params Type[] typesToExclude)
    {
        _typesToExlude = typesToExclude;
    }

    private readonly Type[] _typesToExlude;

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        bool skipAuthorization = _typesToExlude.Any(type => filterContext.ActionDescriptor.ControllerDescriptor.ControllerType == type);

        if (!skipAuthorization)
        {
            base.OnAuthorization(filterContext);
        }
    }
}

Y luego lo registré en mis archivos globales:

filters.Add(new SelectableAuthorizeAttribute(typeof(MyController)));

Espero que sea útil para alguien

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top