2011-09-07 122 views
0


我已经定义了一个自定义的授权属性,它自动应用于解决方案中的所有操作。 在其OnAuthorize方法中,我使用IsDefined方法来查找是否定义了另一个属性,但似乎总是返回false。MVC 3自定义授权属性isDefined始终返回true

编辑:AuthorizeAttr属性在Global.asax中的RegisterGlobalFilters函数中设置,Anon属性直接标记在不需要授权的操作之上。

这里是我的代码:

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

    } 
} 

回答

1

布尔代数的

isDefinedOnAction || isDefinedOnController 

的否定是:

!isDefinedOnAction && !isDefinedOnController 

所以你可能要一个&&条件:

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

,或者如果你想||

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

显然,第一种是更具可读性。

+0

啊! Ofcource! 由于我否定了结果,它正在检查它是否不存在,并且只有其中一个没有该属性让if语句中的代码得到执行。 对不起,发布一个简单的逻辑问题,然后求助! –

+0

说得太快了,由于某种原因,它仍然不起作用! –

+0

@Mats Edvinsson,我测试了代码,它工作正常。 if条件之前的'isDefinedOnAction'和'isDefinedOnController'变量的值是什么?他们都是假的吗?你用'[Anon]'属性装饰了一个控制器还是一个动作? –