Подтвердить что ты не робот

Можете ли вы включить [Авторизовать] для контроллера, но отключите его для одного действия?

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

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

Ответ 1

Я не думаю, что вы можете сделать это со стандартным атрибутом 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 ...
}

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

Ответ 2

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

Ответ 3

Вы можете переопределить метод 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();
        }
    }
}
}

Ответ 4

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

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

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