Атрибут MVC 3 Custom Authorization isDefined всегда возвращает true - PullRequest
0 голосов
/ 07 сентября 2011


Я определил пользовательский атрибут авторизации, и он автоматически применяется ко всем действиям в решении. В его методе OnAuthorize я использую метод IsDefined, чтобы определить, определен ли другой атрибут, но кажется, что он всегда возвращает false.

Редактировать: атрибут AuthorizeAttr устанавливается в функции RegisterGlobalFilters в Global.asax, а атрибут 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 Ответ

1 голос
/ 07 сентября 2011

В булевой алгебре отрицание

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

Очевидно, что первое гораздо более читабельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...