ASP.Net MVC 3: атрибут обратной авторизации - PullRequest
7 голосов
/ 03 ноября 2011

У меня есть простое приложение ASP.Net MVC 3, которое имеет некоторый контроллер и несколько хороших действий.

Теперь, поскольку это приложение на основе пользователя, большинство действий контроллера требуют аутентификации пользователя.,MVC хорошо справляется со встроенным атрибутом Authorize, который вы можете использовать для индивидуального украшения контроллеров и / или действий.

Замечательно, что вы можете применить атрибут только к контроллеру и ко всем действиям для данного контроллерабудет применено это тоже - много печати сохранено;)

Но у меня есть один контроллер с, скажем, 10 действиями.Но я хочу, чтобы одно из действий не применяло атрибут Authorize.

Да, я мог бы применить атрибут к другим 9 и удалить его из контроллера, который будет делать именно то, что мне нужно.Но есть ли способ сохранить его применение к контроллеру и просто исключить одно из действий?

Фактически, хотелось бы что-то вроде ...

[!Authorize] или [NotAuthorize]

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

Ответы [ 2 ]

11 голосов
/ 12 июля 2012

Обратите внимание, что в ASP.NET MVC был добавлен новый атрибут 4.0 , который делает именно это:
[AllowAnonymous]

2 голосов
/ 03 ноября 2011

Фил Хаак недавно написал сообщение в блоге, посвященное именно этому сценарию:

Условные фильтры в ASP.NET MVC 3

Его решение включает в себя написание пользовательского «поставщика условного фильтра», который позволяет назначить условие фильтра атрибутам метода действия.

Подробности и рассуждения в его посте, но код относительно прост. Сначала создайте поставщика фильтров:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;

public class ConditionalFilterProvider : IFilterProvider {
  private readonly 
    IEnumerable<Func<ControllerContext, ActionDescriptor, object>> _conditions;

  public ConditionalFilterProvider(
    IEnumerable<Func<ControllerContext, ActionDescriptor, object>> conditions)
  {

      _conditions = conditions;
  }

  public IEnumerable<Filter> GetFilters(
      ControllerContext controllerContext, 
      ActionDescriptor actionDescriptor) {
    return from condition in _conditions
           select condition(controllerContext, actionDescriptor) into filter
           where filter != null
           select new Filter(filter, FilterScope.Global, null);
  }
}

И затем применить его:

IEnumerable<Func<ControllerContext, ActionDescriptor, object>> conditions = 
    new Func<ControllerContext, ActionDescriptor, object>[] { 

    (c, a) => c.Controller.GetType() != typeof(HomeController) ? 
      new MyFilter() : null,
    (c, a) => a.ActionName.StartsWith("About") ? new SomeFilter() : null
};

var provider = new ConditionalFilterProvider(conditions);
FilterProviders.Providers.Add(provider);
...