ASP.NET MVC: могу ли я сказать [Authorize Roles = "Administrators"] о классе Controller, но иметь одно публичное действие? - PullRequest
5 голосов
/ 29 марта 2010

Я начал с использования проекта по умолчанию AccountController, но расширил / изменил его до неузнаваемости. Однако, как и у оригинала, у меня есть действия LogOn и LogOff.

Очевидно, что действие LogOn должно быть доступно каждому. Однако, поскольку я добавил множество других действий к этому контроллеру (для создания и редактирования пользователей), я хочу, чтобы 99% действий требовали членства в роли администратора.

Я мог бы украсить все свои действия с [Authorize Roles="Administrators"], но есть риск, что я забуду один. Я бы предпочел сделать его безопасным по умолчанию, украсив сам класс контроллера этим атрибутом, а затем ослабить требование к моему LogOn методу. Могу ли я это сделать?

(Например, могу ли я сделать это из коробки без создания пользовательских классов и т. Д. Я не хочу усложнять вещи больше, чем необходимо.)

Ответы [ 3 ]

4 голосов
/ 29 марта 2010

Чтобы переопределить атрибут контроллера на уровне действия, необходимо создать пользовательский атрибут, а затем установить для свойства Order вашего пользовательского атрибута более высокое значение, чем для контроллера AuthorizeAttribute. Я полагаю, что оба атрибута тогда все еще выполняются, если ваш пользовательский атрибут не генерирует результат с немедленным эффектом, таким как перенаправление.

См. Переопределение контроллера AuthorizeAttribute только для одного действия для получения дополнительной информации.

Так что я считаю, что в вашем случае вам просто нужно добавить AuthorizeAttribute в действия, а не на уровне контроллера. Однако вы можете создать модульный тест, чтобы убедиться, что все действия (кроме LogOn) имеют AuthorizeAttribute

2 голосов
/ 05 марта 2013

Спустя слишком много времени, я нашел решение.

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

, которое можно связать с IgnoreAuthorization для действия

public class IgnoreAuthorization : Attribute
{
}
2 голосов
/ 29 марта 2010

Вы можете использовать AuthorizeAttribute на вашем классе

http://msdn.microsoft.com/en-us/library/system.web.mvc.authorizeattribute.aspx

Для расслабления вы можете реализовать, например, атрибут фильтра пользовательских действий, подобный этому (я не проверял, работает ли он).

public class GetRidOfAutorizationAttribute : AuthorizeAttribute 
{
public override void OnAuthorization(AuthorizationContext filterContext)
{

// you can for example do nothing
filterContext.Result = new EmptyResult(); 

}
}
...