Можете ли вы включить [Авторизовать] для контроллера, но отключить его для одного действия?
-
11-07-2019 - |
Вопрос
Я хотел бы использовать [Authorize]
для каждого действия в моем административном контроллере, кроме действия Login
. Р>
[Authorize (Roles = "Administrator")]
public class AdminController : Controller
{
// what can I place here to disable authorize?
public ActionResult Login()
{
return View();
}
}
Решение
Я не думаю, что вы можете сделать это со стандартным атрибутом Authorize, но вы можете получить свой собственный атрибут из AuthorizeAttribute, который принимает список разрешенных действий и разрешает доступ только к этим действиям. Вы можете посмотреть на источник для AuthorizeAttribute на www.codeplex.com , чтобы узнать, как это сделать. Если вы это сделали, это может выглядеть так:
[AdminAuthorize (Roles = "Administrator", Exempt = "Login, Logout") ]
public class AdminController : Controller
{
public ActionResult Login()
{
return View();
}
public ActionResult Login()
{
return View();
}
... other, restricted actions ...
}
РЕДАКТИРОВАТЬ . К вашему сведению, я столкнулся с необходимостью сделать что-то подобное самостоятельно и пошел в другом направлении. Я создал поставщика фильтра авторизации по умолчанию и применил глобальный фильтр авторизации. Поставщик фильтра авторизации использует отражение, чтобы проверить, применяется ли к действию или контроллеру определенный атрибут авторизации, и, если это так, откладывает его. В противном случае применяется фильтр авторизации по умолчанию. Это связано с PublicAttribute, полученным из AuthorizeAttribute, который разрешает публичный доступ. Теперь я получаю защищенный доступ по умолчанию, но могу предоставить публичный доступ через [Public]
, примененный к действию или контроллеру. При необходимости также может применяться более конкретное разрешение. Смотрите мой блог на http: // farm-fresh -code.blogspot.com/2011/04/default-authorization-filter-provider.html р>
Другие советы
Вы можете украсить свой контроллер с помощью [Authorize], а затем вы можете просто украсить метод, который вы хотите исключить, с помощью [AllowAnonymous]
Вы можете переопределить метод OnAuthorization контроллера
protected override void OnAuthorization(AuthorizationContext filterContext)
{
if ((string)(filterContext.RouteData.Values["action"]) == "Login")
{
filterContext.Cancel = true;
filterContext.Result = Login();
}
}
Это работает, но это взлом.
Полный код класса, используемый для тестирования:
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();
}
}
}
}
Может быть, это не так, но я написал свой собственный атрибут:
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);
}
}
}
А потом зарегистрировал его в моих глобальных файлах:
filters.Add(new SelectableAuthorizeAttribute(typeof(MyController)));
Надеюсь, что это будет кому-то полезно