Переопределение контроллера AuthorizeAttribute всего за одно действие
У меня есть контроллер, украшенный атрибутом AuthorizeAttribute. Контроллер содержит несколько действий, требующих аутентификации отдельно от одного действия, которое требует некоторой пользовательской проверки подлинности, предоставляемой CustomAuthorizeAttribute.
Мой вопрос: однажды я добавил [Авторизовать] на уровне контроллера, могу ли я переопределить его (или удалить) с помощью [CustomAuthorize] только на одном действии? Или мне нужно удалить [Authorize] с уровня контроллера и добавить его отдельно для каждого другого действия?
Я прошу исключительно для удобства, потому что я ленив и не хочу украшать каждое действие с помощью AuthorizeAttribute.
[Authorize]
public class MyController : Controller {
//requires authentication
public ViewResult Admin() {
return View();
}
//... a lot more actions requiring authentication
//requires custom authentication
[CustomAuthorize] //never invoked as already failed at controller level
public ViewResult Home() {
return View();
}
}
Ответы
Ответ 1
Вы можете изменить Ордер, в котором выполняются атрибуты (с использованием свойства Order), но я считаю, что в этом случае они все равно будут работать, если не будут получены результаты с немедленным эффектом. Ключ должен иметь наименьший ограничивающий атрибут, применяемый на самом высоком уровне (классе), и получить более ограничительные методы. Если вы хотите, чтобы действие Home
было общедоступным, например, вам нужно было бы удалить атрибут Authorize из класса и применить его к каждому из других методов.
Если действие имеет одинаковый уровень вседозволенности, но имеет другой результат, изменение порядка может быть достаточным. Например, вы обычно перенаправляете на действие Logon
, но для Home
вы хотите перенаправить действие About
. В этом случае укажите атрибут класса Order=2
и атрибут Home
Order=1
.
Ответ 2
В MVC 5 вы можете переопределить авторизацию для любого действия, используя новый атрибут OverrideAuthorization. По сути, вы добавляете его к действию, конфигурация авторизации которого отличается от конфигурации, определенной в контроллере.
Вы делаете это так:
[OverrideAuthorization]
[Authorize(Roles = "Employee")]
public ActionResult List() { ... }
Более подробная информация на http://www.c-sharpcorner.com/UploadFile/ff2f08/filter-overrides-in-Asp-Net-mvc-5/
В ASP.NET Core 2.1 нет атрибута OverrideAuthorization, и единственное, что вы можете сделать, - это сделать действие анонимным, даже если это не контроллер. Дополнительная информация по адресу https://docs.microsoft.com/en-us/aspnet/core/security/authorization/roles?view=aspnetcore-2.1.
Один из вариантов - сделать это так:
[Authorize(Roles = "Admin,Employee")] // admin or employee
public class XController : Controller
{
[Authorize(Roles = "Admin")] // only admin
public ActionResult ActionX() { ... }
[AllowAnonymous] // anyone
public ActionResult ActionX() { ... }
}
Ответ 3
Спустя слишком много времени, я нашел решение. Вам необходимо украсить свой контроллер с помощью пользовательского атрибута AuthorizeAttribute.
public class OverridableAuthorize : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
var action = filterContext.ActionDescriptor;
if(action.IsDefined(typeof(IgnoreAuthorization), true)) return;
var controller = action.ControllerDescriptor;
if(controller.IsDefined(typeof(IgnoreAuthorization), true)) return;
base.OnAuthorization(filterContext);
}
}
Который может быть связан с AllowAnonymous
в действии
[AllowAnonymous]
Ответ 4
Все, что вам нужно, чтобы переопределить [Authorize] из контроллера, для конкретного действия это добавить
[AllowAnonymous]
к действию, которое вы хотите не авторизовать (затем добавьте свой настраиваемый атрибут по мере необходимости).
Смотрите комментарии /intellisense:
Представляет атрибут, который помечает контроллеры и действия, чтобы пропустить System.Web.Mvc.AuthorizeAttribute во время авторизации.