2011-09-07 5 views
0


J'ai défini un attribut d'autorisation personnalisé et il est automatiquement appliqué à toutes les actions de la solution. Dans sa méthode OnAuthorize j'utilise la méthode IsDefined pour trouver si un autre attribut est défini mais il semble qu'il renvoie toujours false.L'attribut d'autorisation personnalisée MVC 3 isDefined retourne toujours vrai

Édition: l'attribut AuthorizeAttr est défini dans la fonction RegisterGlobalFilters dans Global.asax et l'attribut Anon est marqué directement au-dessus des actions qui n'ont pas besoin d'autorisation.

Voici mon code:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] 
public class Anon : Attribute { } 

public class Role : Attribute 
{ 
    public int Id; 
    public Role(int id) 
    { 
     Id = id; 
    } 
} 

public class AuthorizeAttr : AuthorizeAttribute 
{ 
    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     if (!(filterContext.ActionDescriptor.IsDefined(typeof(Anon), false)) || !(filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(Anon), false))) 
     { 
      Procurement.User u = MvcApplication.GetCurrentUser(filterContext.HttpContext); 
      if (u == null || !u.enabled) 
       filterContext.Result = new RedirectResult("/Session/Login?msg=You must log in to use this site.&ReturnUrl=" + filterContext.RequestContext.HttpContext.Request.RawUrl); 
      if (filterContext.ActionDescriptor.IsDefined(typeof(Role), false)) 
      { 
       object[] criterias = filterContext.ActionDescriptor.GetCustomAttributes(typeof(Role), false); 
       bool authorized = true; 
       for (int x = 0; x < criterias.Length; x++) 
       { 
        if (((Role)criterias[x]).Id > u.roleId) 
        { 
         authorized = false; 
         break; 
        } 
       } 

       if (!authorized) 
       { 
        ContentResult C = new ContentResult(); 
        C.Content = "<h1><b>The resource is unavailable!</b></h1>"; 
        filterContext.Result = C; 
       } 
      } 
     } 

    } 
} 

Répondre

1

En algèbre booléenne la négation de

isDefinedOnAction || isDefinedOnController 

est:

!isDefinedOnAction && !isDefinedOnController 

Donc, vous voulez probablement une condition &&:

public override void OnAuthorization(AuthorizationContext filterContext) 
{ 
    var isDefinedOnAction = filterContext.ActionDescriptor.IsDefined(typeof(Anon), false); 
    var isDefinedOnController = filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(Anon), false); 
    if (!isDefinedOnAction && !isDefinedOnController) 
    { 
     ... the Anon attribute is not present neither on an action nor on a controller 
     => perform your authorization here 
    } 
} 

ou si vous voulez ||:

public override void OnAuthorization(AuthorizationContext filterContext) 
{ 
    var isDefinedOnAction = filterContext.ActionDescriptor.IsDefined(typeof(Anon), false); 
    var isDefinedOnController = filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(Anon), false); 
    if (isDefinedOnAction || isDefinedOnController) 
    { 
     ... the attribute is present on either a controller or an action 
     => do nothing here 
    } 
    else 
    { 
     ... perform your authorization here 
    } 
} 

Il est évident que le premier est de loin plus facile à lire.

+0

AH! Ofcource! Puisque je nie le résultat, il vérifie s'il n'existe pas et seul l'un d'entre eux ne possédant pas l'attribut permet d'exécuter le code dans l'instruction if. Désolé de poster un problème logique simple et puis de l'aide! –

+0

parlé trop tôt, il ne fonctionne toujours pas pour une raison quelconque! –

+0

@Mats Edvinsson, j'ai testé le code et ça a bien fonctionné. Quelles sont les valeurs des variables 'isDefinedOnAction' et' isDefinedOnController' avant la condition if? Sont-ils tous les deux faux? Avez-vous décoré un contrôleur ou une action avec l'attribut '[Anon]'? –

Questions connexes