Pouvez-vous activer [Autoriser] pour le contrôleur mais le désactiver pour une seule action?

StackOverflow https://stackoverflow.com/questions/329500

  •  11-07-2019
  •  | 
  •  

Question

J'aimerais utiliser [Autoriser] pour chaque action de mon contrôleur d'administrateur, à l'exception de l'action Login .

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

La solution

Je ne pense pas que vous puissiez faire cela avec l'attribut standard Authorize, mais vous pouvez dériver votre propre attribut à partir de AuthorizeAttribute, qui répertorie les actions à autoriser et permet l'accès uniquement à ces actions. Vous pouvez consulter la source de AuthorizeAttribute à l'adresse www.codeplex.com pour savoir comment procéder. Si vous le faisiez, cela pourrait ressembler à:

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

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

    ... other, restricted actions ...
}

MODIFIER : À titre d'information, j'ai finalement eu besoin de faire quelque chose de similaire par moi-même et j'ai pris une direction différente. J'ai créé un fournisseur de filtres d'autorisation par défaut et appliqué un filtre d'autorisation global. Le fournisseur de filtres d'autorisation utilise la réflexion pour vérifier si une action ou un contrôleur a un attribut d'autorisation spécifique appliqué et, le cas échéant, le diffère. Sinon, il applique un filtre d'autorisation par défaut. Ceci est associé à un PublicAttribute dérivé de AuthorizeAttribute qui permet un accès public. Maintenant, je reçois un accès sécurisé par défaut, mais je peux accorder un accès public via [Public] appliqué à une action ou à un contrôleur. Une autorisation plus spécifique peut également être appliquée si nécessaire. Voir mon blog à l'adresse http: // farm-fresh -code.blogspot.com/2011/04/default-authorization-filter-provider.html

Autres conseils

Vous pouvez décorer votre contrôleur avec [Autoriser], puis décorer simplement la méthode que vous souhaitez exempter avec [AllowAnonymous]

Vous pouvez remplacer la méthode OnAuthorization du contrôleur

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

Cela fonctionne mais c'est un hack.

Code de classe complet utilisé pour les tests:

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

Peut-être que ce n'est pas réel, mais j'ai écrit mon attribut personnalisé:

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

Et ensuite enregistré dans mes fichiers globaux:

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

J'espère que cela sera utile à quelqu'un

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top