2009-08-22 5 views
9

Je me demandais si/comment je peux remplacer le comportement [Authorize] par défaut dans ASP.NET MVC. Je sais que je peux créer un nouveau filtre d'action, faire mon propre attribut et ainsi de suite; Je suis simplement intéressé si je peux simplement changer le comportement [Authorize] et remplacer son fonctionnement avec mon propre code?Est-il possible de remplacer le comportement par défaut de [Authorize] dans ASP.NET MVC?

Modifier: Les gars et les filles. J'apprécie votre contribution, mais comme je l'ai écrit, je suis pas cherchant à introduire un nouvel attribut [XYZAuthorize]. Je suis conscient de la façon de faire cela. Je veux garder la notation [Autoriser] mais juste changer comment cela fonctionne.

+7

Pourquoi voudriez-vous conserver le nom "authorize" de l'attribut et changer son comportement? C'est une mauvaise chose à faire. Les gens, quand ils voient [Autoriser], ils attendent ce qu'il va faire. Si vous le changez, lire votre code sera beaucoup plus difficile. Même pour vous dans le futur. –

+3

Je ne suis pas d'accord; Si vous le dites, tout opérateur ou méthode surchargée/dépassement serait erroné. – Alex

+5

@Alex: Je ne suis pas d'accord. La surcharge de l'opérateur est une bonne chose. C'est une mauvaise chose d'en abuser. L'exemple habituel: vous avez une classe Vector, vous créez l'opérateur "+". C'est évident ce que ça va faire. Mais qu'en est-il de l'opérateur "*"? C'est une mauvaise chose à faire, est-ce un produit croisé ou un produit scalaire? Ou un autre type de produit personnalisé? Donc, la surcharge est bonne, mais c'est très mauvais quand on masque les conventions. –

Répondre

6

Oui, jetez un oeil à la documentation MSDN pour AuthorizeAttribute: http://msdn.microsoft.com/en-us/library/system.web.mvc.authorizeattribute.aspx.

Fondamentalement, vous pouvez remplacer la méthode OnAuthorization() et personnaliser le comportement. Il existe également d'autres méthodes virtuelles sur l'attribut.

EDIT: Comme Bruno l'a souligné, vous pouvez remplacer la méthode AuthorizeCore(). La principale différence étant que AuthorizeCore() prend un HttpContextBase, tandis que OnAuthorization() prend un AuthorizationContext. Une instance de AuthorizationContext vous fournit plus d'informations, telles que le Controller, le RequestContext et le RouteData. Il vous permet également de spécifier un objet ActionResult. AuthorizeCore() est plus restreint dans les informations auxquelles vous pouvez accéder ainsi que le résultat que vous pouvez retourner, mais si vous avez besoin d'autoriser les données mises en cache, alors votre logique doit gérer le cas où vous n'avez pas de ces données supplémentaires (puisque les données sont servies à partir du cache avant que la demande soit acheminée via le pipeline MVC).

Comme toujours, vous devez comprendre votre scénario et les outils disponibles et les compromis entre eux.

+1

AuthorizeAttribute ne contient pas de méthode OnAuthorize. Voulez-vous dire OnAuthorization()? Quoi qu'il en soit, vous ne devriez pas le changer, à moins que vous ne vouliez du mal de tête lors de l'implémentation de la mise en cache, puisque c'est une méthode (OnAuthorization) qui s'en occupe. –

9

Vous pouvez sous-classer le filtre AuthorizeAttribute et y placer votre propre logique.

Voyons un exemple. Disons que vous voulez toujours autoriser les connexions locales. Cependant, s'il s'agit d'une connexion distante, vous souhaitez conserver la logique d'autorisation habituelle.

Vous pouvez faire quelque chose comme:

public class LocalPermittedAuthorizeAttribute : AuthorizeAttribute 
{ 
    protected override bool AuthorizeCore(HttpContextBase httpContext) 
     { 
      return (httpContext.Request.IsLocal || base.AuthorizeCore(httpContext))); 
     } 
} 

Ou vous pouvez toujours autoriser une certaine adresse à distance (votre machine, par exemple).

C'est tout!

Edit: oublié de mentionner, vous utiliserez la même chose que vous utilisez le filtre AuthorizeAttribute:

class MyController : Controller 
{ 
    [LocalPermittedAuthorize] 
    public ActionResult Fire() 
    { 
     Missile.Fire(Datetime.Now); 
    } 
} 
2

Je ne vois que deux façons: impérieuses méthode AuthorizeAttribute.OnAuthorization ou créer votre propre attribut authorize à partir de zéro.

1) très simple:

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

     /// your behavior here 
    } 
} 

2) trop facile - il suffit de regarder à la source ASP.NET MVC, fichier AuthorizeAttribute.cs

+1

Vous devriez éviter de créer un attribut d'autorisation à partir de zéro si vous ne voulez pas un mal de tête lorsque vous implémentera la mise en cache ... l'attribut Authorize d'ASP.NET MVC traite déjà de cet aspect. –

1

Il semble que vous pouvez implémenter un filtre personnalisé comme d'habitude (et hériter de AuthorizeAttribute si vous le souhaitez), puis créer un nouvel ActionInvoker qui hérite de ControllerActionInvoker et remplace GetFilters.Dans GetFilters, vous appelez base.GetFilters() pour obtenir la liste des filtres, parcourir les AuthorizationFilters et remplacer les appels à AuthorizeFilter par des appels à votre filtre personnalisé.

Une autre possibilité consiste à implémenter des fournisseurs d'appartenances et de rôles personnalisés, en fonction de ce que vous essayez de faire.

+0

Pourquoi aurait-on besoin d'un ActionInvoker personnalisé uniquement pour un filtre d'autorisation simple? –

+0

@Bruno: Parce qu'il ne semble pas y avoir d'autre moyen de remplacer un filtre de framework par out propre, juste pour en créer de nouveaux. – svinto

+0

Mais ... pourquoi voudrait-on * remplacer * le filtre cadre? Regarde mon commentaire à la question. C'est une chose stupide à faire. –

4

Implémentez votre propre fournisseur de rôles et configurez votre application pour l'utiliser. Ensuite, l'attribut Autoriser respectera votre code d'autorisation.

Questions connexes