ASP MVC Авторизовать все действия кроме нескольких - PullRequest
27 голосов
/ 23 апреля 2009

У меня есть контроллер, и я хотел бы требовать авторизацию для всех действий по умолчанию, кроме пары. Таким образом, в приведенном ниже примере все действия должны требовать аутентификации, кроме индекса. Я не хочу украшать каждое действие с помощью Авторизации, я просто хочу переопределить авторизацию по умолчанию в определенных обстоятельствах, возможно, с помощью специального фильтра, например NotAuthorize.

[Authorize]
public class HomeController : BaseController
{
    [NotAuthorize]
    public ActionResult Index()
    {
        // This one wont
        return View();
    }

    public ActionResult About()
    {
        // This action will require authorization
        return View();
    }
}

Ответы [ 7 ]

39 голосов
/ 23 апреля 2009

Хорошо, это то, что я сделал. Если есть лучший способ, дайте мне знать.

public class NotAuthorizeAttribute : FilterAttribute
{
    // Does nothing, just used for decoration
}

public class BaseController : Controller
{
    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // Check if this action has NotAuthorizeAttribute
        object[] attributes = filterContext.ActionDescriptor.GetCustomAttributes(true);
        if (attributes.Any(a => a is NotAuthorizeAttribute)) return;

        // Must login
        if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            filterContext.Result = new HttpUnauthorizedResult();
        }
    }
}
28 голосов
/ 12 марта 2012

А как же [AllowAnonymous] ??

9 голосов
/ 18 февраля 2013

MVC4 имеет новый атрибут, предназначенный именно для этого [AllowAnonymous] (как указал Энрико)

[AllowAnonymous]
public ActionResult Register()

Читать все об этом здесь:

http://blogs.msdn.com/b/rickandy/archive/2012/03/23/securing-your-asp-net-mvc-4-app-and-the-new-allowanonymous-attribute.aspx

6 голосов
/ 01 апреля 2012

Используйте пользовательский фильтр, как описано в Защита приложения ASP.NET MVC 3 .

6 голосов
/ 06 февраля 2010

Вот что я бы сделал, аналогично ответу Крейга с парой изменений:

1) Создайте обычный атрибут, производный от System.Attribute (нет необходимости выводить из FilterAttribute, поскольку вы не собираетесь использовать ничего, что обеспечивает FilterAttribute).

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

Attribute
    AuthorizationAttribute
         AuthorizationNotRequiredAttribute
         AuthorizationAdminUserRequiredAttribute
             AuthorizationSuperUserRequiredAttribute

2) В вашем BaseController переопределите метод OnAuthorization вместо метода OnActionExecuting:

protected override void OnAuthorization(AuthorizationContext filterContext)
{
    var authorizationAttributes = filterContext.ActionDescriptor.GetCustomAttributes(true).OfType<AuthorizationAttribute>();
    bool accountRequired = !authorizationAttributes.Any(aa => aa is AuthorizationNotRequiredAttribute);

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

5 голосов
/ 02 марта 2014

Отметьте контроллер с помощью [Авторизовать]

[Авторизоваться] открытый класс YourController: ApiController

Отметьте действия, которые вы хотите сделать общедоступными:

[AllowAnonymous]

1 голос
/ 29 апреля 2011

Немного опоздал на вечеринку, но я закончил тем, что создал атрибут авторизации уровня контроллера и атрибут авторизации уровня действия и просто пропустил аутентификацию контроллера, если у действия был собственный атрибут аутентификации. Смотрите код здесь:

https://gist.github.com/948822

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...