Применение фильтра действий ко всем действиям контроллера (C # / ASP.NET MVC)

Я создал новый фильтр действий (атрибут, аналогичный [Authorize]), который разрешает доступ к действию контроллера на основе значения сеанса. Однако я в основном украшаю все свои действия контроллера этим атрибутом (за исключением очень немногих).

Итак, я подумал, что было бы лучше, чтобы этот фильтр действий всегда выполнялся кроме в тех случаях, когда я прикрепляю атрибут [ExemptFromAuthorize] к действию контроллера? (Может быть, путем наследования моему собственному классу контроллера?)

Как я могу это сделать?


person Alex    schedule 27.08.2009    source источник
comment
Это старый вопрос, и в MVC4 есть новый атрибут AllowAnonymous, созданный специально для этого.   -  person Carlos Blanco    schedule 06.08.2013


Ответы (7)


Запуск с jeef3 Ответ, я это придумал. Он мог бы использовать больше проверки ошибок и надежности, например, несколько действий с разделителями, но общая идея работает.

В вашем конкретном случае вы можете проверить значение сеанса и также решить вернуться из авторизации.

public class AuthorizeWithExemptionsAttribute : AuthorizeAttribute
{
    public string Exemption { get; set; }
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        if (filterContext.RouteData.GetRequiredString("action") == Exemption)
            return;

        base.OnAuthorization(filterContext);
    }

}

Использование:

[AuthorizeWithExemptions(Roles="admin", ExemptAction="Index")]
public class AdminController : Controller
...
person Ben Robbins    schedule 27.08.2009

Посмотрите мою статью о codeproject -

http://www.codeproject.com/KB/web-security/AuthorizeWithExemptions.aspx

В этой статье я предоставлю вам решение для защиты контроллеров приложения ASP.NET MVC таким образом, чтобы были защищены все действия, кроме тех, которые вы определяете как небезопасные.

сниппер из кода:

public override void OnAuthorization(AuthorizationContext filterContext)
{
    ActionDescriptor action = filterContext.ActionDescriptor;
    bool IsUnsecured = action.GetCustomAttributes(
                         typeof(UnsecuredActionAttribute), true).Count() > 0;

    //If doesn't have UnsecuredActionAttribute - then do the authorization
    filterContext.HttpContext.SkipAuthorization = IsUnsecured;

    base.OnAuthorization(filterContext);
}
person Maxim    schedule 27.08.2010

Я понимаю, что вопрос устарел, но в любом случае ... Если вы хотите применить фильтр ко всем действиям, просто добавьте следующие строки в Global.asax:

protected void Application_Start()
{
    // your code here and then
    RegisterGlobalFilters(GlobalFilters.Filters);
}    

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new MyActionFilterAttribute());
}

А в фильтре действий вы можете просто проверить, есть ли у действия какие-либо другие атрибуты, следующим образом:

public void OnActionExecuting(ActionExecutingContext filterContext)
{
    if (filterContext.ActionDescriptor.IsDefined(typeof(AnotherActionAttribute), false))
    {
        // do what you want to do
    }
}
person Andrew    schedule 17.05.2013
comment
ActionDescriptor в настоящее время не определяет IsDefined. - person hallizh; 09.08.2016
comment
Для тех, кто подходит к этому вопросу из-за вопроса в заголовке, первая часть этого является фактическим ответом на то, как запускать фильтр действий для каждого действия контроллера. - person Chris Marasti-Georg; 14.08.2017

Может быть, попробовать добавить свойство Except к вашему первому атрибуту?

[MyAuthenticate(Exempt="View")]
public class MyController : Controller
{
    public ActionResult Edit()
    {
        // Protected
    }

    public ActionResult View()
    {
        // Accessible by all
    }
}
person jeef3    schedule 27.08.2009
comment
Но как будет работать логика в фильтре действий? (Фактически заставляет Освобожденный работать)? - person Alex; 28.08.2009

Вы можете добавить атрибут в класс, чтобы он применялся ко всем методам этого класса.

[Authenticate]
public class AccountController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}

Я не знаю, как исключить конкретный метод из атрибута уровня класса. Может быть, использовать отдельный контроллер для неаутентифицированных запросов?

person John Sheehan    schedule 27.08.2009
comment
Создание отдельных контроллеров привело бы к спагеттификации моего кода ... исключение определенных методов из атрибута уровня класса было бы именно тем, что мне нужно. - person Alex; 28.08.2009

Для всех, кто читает это в 2013+, MVC4 теперь поддерживает использование [AllowAnonymous]

Вы можете установить авторизацию на контроллере, а затем Разрешить анонимность для любых функций, которые вы не хотите авторизовать.

Пример:

[Авторизовать] открытый класс HomeController: Controller {

[AllowAnonymous]
public ActionResult Index()
{

} 

}

Будет ли это работать с настраиваемым фильтром [MyAuthorize] или только с [Authorize]

person lanierhall    schedule 04.11.2013
comment
Если вы унаследовали свой [MyAuthorize] от AuthorizeAttribute, [AllowAnonymous] подойдет вам. - person Gh61; 07.08.2014

Для всех, кто читал это в 2013+, MVC4 теперь поддерживает использование [AllowAnonymous]

Вы можете установить авторизацию на контроллере, а затем Разрешить анонимность для любых функций, которые вы не хотите авторизовать.

Пример:

[Authorize]
public class HomeController : Controller
{

    [AllowAnonymous]
    public ActionResult Index()
    {

    }
}
person Kyle    schedule 28.03.2013