Вы можете создать свой собственный атрибут Authorize, например «AuthorizeAllExceptAdmin».Внутри этого класса вам просто нужно проверить, был ли текущий пользователь администратором, и если они отклонили его, в противном случае примите его.
Вот хороший учебник , но вы 'Вероятно, в итоге получится что-то вроде:
public class AuthorizeAllExceptAdmin : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
return !httpContext.User.IsInRole(Constants.ROLES_ADMINISTRATOR);
}
}
Тогда ваш метод контроллера станет следующим:
[AuthorizeAllExceptAdmin]
public ActionResult SomethingOnlyNonAdminsCanDo()
{
}
Вот пример пользовательского атрибута, который принимает роли для отказа.
public class DoNotAuthorize : AuthorizeAttribute
{
private IEnumerable<string> _rolesToReject;
public DoNotAuthorize(IEnumerable<string> rolesToReject)
{
_rolesToReject = rolesToReject;
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
foreach (var role in _rolesToReject)
{
if (httpContext.User.IsInRole(role))
return false;
}
return true;
}
}
Тогда ваш метод контроллера становится следующим:
[DoNotAuthorize(new [] {Constants.ROLES_ADMINISTRATOR})]
public ActionResult SomethingOnlyNonAdminsCanDo()
{
}
Я бы немного подумал, прежде чем выбрать один из вышеперечисленных вариантов.Если вы думаете, что у вас будет несколько методов (или целых контроллеров) с аналогичными требованиями к авторизации (т. Е. Несколько действий, которые администратор не может выполнить), то я остановлюсь на непараметризованном настраиваемом атрибуте.Таким образом, вы можете развить их все вместе (только изменив пользовательский атрибут) позже.Например, может позже вы захотите, чтобы администраторы могли переходить в специальный режим, в котором они могут выполнять эти действия.
В качестве альтернативы, если авторизация более разнообразна среди действий, тогда использование параметризованного списка имеет смысл, поскольку они будут развиваться относительно независимо.