Можете ли вы включить [Авторизовать] для контроллера, но отключить его для одного действия? - PullRequest
17 голосов
/ 01 декабря 2008

Я хотел бы использовать [Authorize] для каждого действия в моем административном контроллере, кроме действия Login.

[Authorize (Roles = "Administrator")]
public class AdminController : Controller
{
    // what can I place here to disable authorize?
    public ActionResult Login()
    {
        return View();
    }
}

Ответы [ 4 ]

25 голосов
/ 09 мая 2013

Вы можете украсить свой контроллер с помощью [Authorize], а затем вы можете просто украсить метод, который вы хотите исключить, с помощью [AllowAnonymous]

14 голосов
/ 01 декабря 2008

Я не думаю, что вы можете сделать это со стандартным атрибутом Authorize, но вы можете получить свой собственный атрибут из AuthorizeAttribute, который принимает список разрешенных действий и разрешает доступ только к этим действиям. Вы можете посмотреть на источник для AuthorizeAttribute на www.codeplex.com для идей о том, как это сделать. Если вы это сделали, это может выглядеть так:

[AdminAuthorize (Roles = "Administrator", Exempt = "Login, Logout") ]
public class AdminController : Controller
{
    public ActionResult Login()
    {
        return View();
    }

    public ActionResult Login()
    {
        return View();
    }

    ... other, restricted actions ...
}

РЕДАКТИРОВАТЬ : К вашему сведению, в итоге я столкнулся с необходимостью сделать что-то подобное самостоятельно и пошел в другом направлении. Я создал поставщика фильтра авторизации по умолчанию и применил глобальный фильтр авторизации. Поставщик фильтра авторизации использует отражение, чтобы проверить, применяется ли к действию или контроллеру определенный атрибут авторизации, и, если это так, откладывает его. В противном случае применяется фильтр авторизации по умолчанию. Это связано с PublicAttribute, полученным из AuthorizeAttribute, который разрешает публичный доступ. Теперь я получаю защищенный доступ по умолчанию, но могу предоставить публичный доступ через [Public], примененный к действию или контроллеру. При необходимости также может применяться более конкретное разрешение. См. Мой блог на http://farm -fresh-code.blogspot.com / 2011/04 / default-authorization-filter-provider.html

4 голосов
/ 01 декабря 2008

Вы можете переопределить метод OnAuthorization контроллера

    protected override void OnAuthorization(AuthorizationContext filterContext)
    {
        if ((string)(filterContext.RouteData.Values["action"]) == "Login")
        {
            filterContext.Cancel = true;
            filterContext.Result = Login();
        }
    }

Это работает, но это взлом.

Полный код класса, используемый для тестирования:

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

namespace MvcApplication2.Controllers
{
[HandleError]
[Authorize]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewData["Title"] = "Home Page";
        ViewData["Message"] = "Welcome to ASP.NET MVC!";

        return View();
    }


    public ActionResult About()
    {
        ViewData["Title"] = "About Page";

        return View();
    }


    protected override void OnAuthorization(AuthorizationContext filterContext)
    {
        if ((string)(filterContext.RouteData.Values["action"]) == "Index")
        {
            filterContext.Cancel = true;
            filterContext.Result = Index();
        }
    }
}
}
1 голос
/ 19 июля 2012

Может быть, это не актуально, но я написал свой собственный атрибут:

public class SelectableAuthorizeAttribute : AuthorizeAttribute
{
    public SelectableAuthorizeAttribute(params Type[] typesToExclude)
    {
        _typesToExlude = typesToExclude;
    }

    private readonly Type[] _typesToExlude;

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        bool skipAuthorization = _typesToExlude.Any(type => filterContext.ActionDescriptor.ControllerDescriptor.ControllerType == type);

        if (!skipAuthorization)
        {
            base.OnAuthorization(filterContext);
        }
    }
}

А затем зарегистрировал его в моих глобальных файлах:

filters.Add(new SelectableAuthorizeAttribute(typeof(MyController)));

Надеюсь, что это будет кому-то полезно

...