você pode ativar [autorizar] para o controlador, mas desativá-lo para uma única ação?
-
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();
}
}
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