você pode ativar [autorizar] para o controlador, mas desativá-lo para uma única ação?

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

  •  11-07-2019
  •  | 
  •  

Pergunta

Eu gostaria de usar [Authorize] para cada ação no meu controlador de administrador, exceto a ação Login.

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

Solução

Eu não acho que você pode fazer isso com o atributo padrão Autorizar, mas você pode derivar seu próprio atributo do AuthorizeAttribute que leva uma lista de ações para permitir e permite o acesso a apenas essas ações. Você pode olhar para a fonte para o AuthorizeAttribute em www.codeplex.com de ideias sobre como fazer isso. Se você fez, isso pode parecer:

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

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

    ... other, restricted actions ...
}

Editar : FYI, eu finalmente encontrei uma necessidade de fazer algo semelhante no meu próprio e eu fui uma direção diferente. Eu criei um provedor de filtro de autorização padrão e aplicar um filtro de autorizar global. O filtro de autorização usos provedor de reflexão para verificar se uma ação ou controlador tem um determinado atributo autorizar aplicada e, em caso afirmativo, adia a ele. Caso contrário, ele aplica um filtro de autorização padrão. Este é acoplado com um PublicAttribute derivado de AuthorizeAttribute que permite o acesso público. Agora, fico com acesso seguro padrão, mas pode conceder acesso público via [Public] aplicado a uma ação ou controlador. Mais autorização específica também pode ser aplicado conforme necessário. Ver meu blog em http: // farm-fresco -code.blogspot.com/2011/04/default-authorization-filter-provider.html

Outras dicas

Você pode decorar o seu controlador com [autorizar] e, em seguida, você pode simplesmente decorar o método que pretende isentar com [AllowAnonymous]

Você poderia substituir o método OnAuthorization do controlador

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

Este funciona, mas ele é um hack.

código da classe completa usado para testes:

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

Pode ser que não é real, mas eu escrevi o meu 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);
        }
    }
}

E, em seguida, registrado em meus filetrs globais:

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

A esperança de que será útil para alguém

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top