Asp.net MVC4: autoriser à la fois le contrôleur et l'action

, Si j'ai l'Autoriser attribut sur le contrôleur et l'action, qui prendra effet? Ou les deux prendront-ils effet?

64
demandé sur John Bubriski 2013-05-23 13:10:23

3 réponses

Vous avez demandé:

Si J'ai L'attribut Authorize sur le contrôleur et l'action, lequel prendra l'effet? Les deux?

Pour répondre à cela simplement: les deux. L'effet est de AND, les deux restrictions ensemble. Je vais vous expliquer pourquoi ci-dessous ...

Détails

Donc, il y a quelques raisons pour lesquelles vous pourriez demander ceci.

  1. Vous voulez savoir comment appliquer une contrainte supplémentaire à une Action par rapport à une méthode. par exemple
    • à niveau du contrôleur, appliquer les utilisateurs dans le rôle "utilisateur"
    • au niveau de l'action, appliquez en outre les utilisateurs dans le rôle "admin"
  2. Vous souhaitez remplacer la contrainte du contrôleur au niveau de l'action
  3. Vous souhaitez supprimer la contrainte du contrôleur au niveau de l'action et rendre la méthode accessible aux utilisateurs anonymes

Vous n'avez pas spécifié votre version MVC, donc je vais supposer la dernière à partir d'aujourd'hui (MVC 4.5). Cependant, cela ne changera pas la réponse beaucoup même si vous utilisiez MVC 3.

[Anonymous] remplace le contrôleur [Authorize] (Cas 3)

Cas 3. Je n'ai pas besoin de la couverture (l'utilisation de [AllowAnonymous]) comme il a été répondu fini SI et sur le web déjà. Autant dire: si vous spécifiez [AllowAnonymous] sur une action, cela rendra cette action publique même si le contrôleur a [Authorize] dessus.

Vous pouvez également soumettre un site web entier à l'autorisation de en utilisant un filtre global , et utiliser AllowAnonymous sur le peu d'actions ou de contrôleurs que vous souhaitez rendre publique.

[Authorize] est additif (cas 1)

Le Cas 1 est facile. Prenez le contrôleur suivant comme exemple:

[Authorize(Roles="user")]
public class HomeController : Controller {
    public ActionResult AllUsersIndex() {
        return View();
    }

    [Authorize(Roles = "admin")]
    public ActionResult AdminUsersIndex() {
        return View();
    }
}

Par défaut, {[11] } met toutes les Actions du contrôleur à la disposition des comptes dans le rôle "Utilisateur" uniquement. Par conséquent, l'accès AllUsersIndex, vous devez être dans le rôle. Toutefois, pour l'accès AdminUsersIndex, vous devez être à la fois dans "l'utilisateur" et le rôle "admin". Par exemple:

  • Nom D'utilisateur: Bob, rôles: utilisateur, ne peut pas accéder à AdminUsersIndex, mais peut accéder à AllUsersIndex
  • nom d'utilisateur: Jane, Rôles: admin, ne accès AdminUsersIndex ou AllUsersIndex
  • nom d'utilisateur: Tim, les Rôles: l'utilisateur et admin, peut accès AdminUsersIndex et AllUsersIndex

Cela illustre que l'attribut [Authorize] est additif. Cela est également vrai de la Users propriété de l'attribut, qui peut être combiné avec Roles pour le rendre encore plus restrictives.

, Ce comportement est dû à la façon dont les attributs de contrôleur et d'action fonctionnent. Les attributs sont enchaînés et appliqués dans le contrôleur de commande puis l'action. Si le premier refuse l'autorisation, le contrôle revient et l'attribut de l'action n'est pas appelé. Si le premier passe l'autorisation, le second est également vérifié. Vous pouvez remplacer cet ordre en spécifiant Order (par exemple [Authorize(Roles = "user", Order = 2)]).

Primordial [Authorize] (cas 2)

Le Cas 2 est plus délicat. Rappelons d'en haut que le [Authorize] les attributs sont examinés dans l'ordre (Global puis) contrôleur puis Action. Le premier à détecter que l'utilisateur n'est pas éligible pour être autorisé gagne, les autres ne sont pas appelés.

Une façon de contourner cela est de définir deux nouveaux attributs comme ci-dessous. Le [OverrideAuthorize] ne fait rien d'autre que de reporter à [Authorize]; son seul but est de définir un type que nous pouvons vérifier. Le [DefaultAuthorize] nous permet de vérifier si l'Action appelée dans la requête est décorée d'un [OverrideAuthorize]. Si c'est pour nous reporter à la vérification D'autorisation D'Action, sinon nous procédons à la vérification du niveau du contrôleur.

public class DefaultAuthorizeAttribute : AuthorizeAttribute {
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        var action = filterContext.ActionDescriptor;
        if (action.IsDefined(typeof(OverrideAuthorizeAttribute), true)) return;

        base.OnAuthorization(filterContext);
    }
}
public class OverrideAuthorizeAttribute : AuthorizeAttribute {
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);
    }
}

Nous pouvons alors l'utiliser comme ceci:

[DefaultAuthorize(Roles="user")]
public class HomeController : Controller {
    // Available to accounts in the "user" role
    public ActionResult AllUsersIndex() {
        return View();
    }
    // Available only to accounts both in the "user" and "admin" role
    [Authorize(Roles = "admin")]
    public ActionResult AdminUsersIndex() {
        return View();
    }
    // Available to accounts in the "superuser" role even if not in "user" role
    [OverrideAuthorize(Roles = "superuser")]
    public ActionResult SuperusersIndex() {
        return View();
    }
}

Dans l'exemple ci-dessus SuperusersIndex est disponible pour un compte qui a le rôle "superutilisateur", même s'il n'a pas le rôle "utilisateur".

134
répondu Andy Brown 2017-05-23 11:47:27

Je voudrais ajouter quelque chose à la substitution de [Authorize] (cas 2)

OverrideAuthorizeAttribute et Defaultautorizeattribute fonctionne bien, mais je découvre que vous pouvez également utiliser OverrideAuthorizationAttribute qui remplace les filtres d'autorisation définis à un niveau supérieur.

[Authorize(Roles="user")]
public class HomeController : Controller {
    // Available to accounts in the "user" role
    public ActionResult AllUsersIndex() {
        return View();
    }
    // Available only to accounts both in the "user" and "admin" role
    [Authorize(Roles = "admin")]
    public ActionResult AdminUsersIndex() {
        return View();
    }
    // Available to accounts in the "superuser" role even if not in "user" role
    [OverrideAuthorization()]
    [Authorize(Roles = "superuser")]
    public ActionResult SuperusersIndex() {
        return View();
    }
}
36
répondu Akodo_Shado 2014-04-09 10:35:05

Si l'utiliser sur contrôleur puis, toutes les méthodes de ce contrôleur sera effectuée.

[Authorize]
public class SomeController(){

    // all actions are effected
    public ActionResult Action1
    public ActionResult Action2

Si vous voulez empêcher l'une de ces actions, vous pouvez utiliser quelque chose comme ceci:

[Authorize]
public class SomeController(){

    // all actions are effected
    public ActionResult Action1
    public ActionResult Action2

    [AllowAnonymous]
    public ActionResult Action3 // only this method is not effected...
0
répondu AliRıza Adıyahşi 2013-05-23 09:14:15