Свойства настраиваемого атрибута веб-Api

Я пытаюсь расширить его атрибут авторизации по умолчанию для Api, чтобы позволить аутентифицированным пользователям иметь доступ к набору действий, даже если они не зарегистрированы в приложении (например, они не имеют роли).

 public class AuthorizeVerifiedUsersAttribute : AuthorizeAttribute
    {
        /// <summary>
        /// Gets or sets the authorized roles.
        /// </summary>
        public new string Roles { get { return base.Roles; } set { base.Roles = value; } }

        /// <summary>
        ///  Gets or sets the authorized users.
        /// </summary>
        public new string Users { get { return base.Users; } set { base.Users = value; } }

        private bool _bypassValidation;
        /// <summary>
        /// Gets of sets a controller or an action as an authorization exception
        /// </summary>
        public virtual bool BypassValidation
        {
            get
            {
                Debug.WriteLine("get:" + TypeId.GetHashCode() + " " + _bypassValidation);
                return _bypassValidation;
            }
            set
            {
                Debug.WriteLine("set:" + TypeId.GetHashCode() + " " + value);
                _bypassValidation = value;
            }
        }

        protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            if (HttpContext.Current.User.Identity.IsAuthenticated)
            {
                if (BypassValidation)
                {
                    return true;
                }
                else
                {
                   //return false if user is unverified

                }
            }

            return base.IsAuthorized(actionContext);
        }
    }

И он используется следующим образом:

 [AuthorizeVerifiedUsers]
 public class UserProfileController : ApiController
 {

    [AuthorizeVerifiedUsers(BypassValidation = true)]
    public bool Verify(string verificationCode)
    {}
 }

Пока это действие является единственным, использующим BypassValidation = true.

Проблема возникает из-за того, что свойство BypassValidation является ложным для действия, даже если окно Debug - используется в свойстве BypassValidation - показывает следующее:

set: 26833123 True set: 39602703 True get: 43424763 False get: 43424763 False get: 43424763 False//вызов, который должен иметь "True"...

Я заметил две вещи:

  • ТипId (уникальный идентификатор для атрибута) различается между вызовами с BypassValidation = true и теми, у которых BypassValidation = false.
  • Идентификатор '43424763' не имеет соответствующего набора

Любые идеи?

Спасибо заранее, Joao

Ответ 1

Как работает веб-API, так это то, что атрибут authorize вызывается для родительской области, в этом случае необходимо выполнить контроллер и переопределить (атрибут authorize для действия) вручную (Пожалуйста, поправьте меня, если я ошибаюсь).

Следовательно, решение может выглядеть следующим образом:

public class AuthorizeVerifiedUsersAttribute : AuthorizeAttribute
{
  (...)

  protected override bool IsAuthorized(HttpActionContext actionContext)
  {

     if (HttpContext.Current.User.Identity.IsAuthenticated)
     {
        //retrieve controller action authorization attributes
        var authorizeAttributes = actionContext.ActionDescriptor.GetCustomAttributes<AuthorizeVerifiedUsersAttribute>();

        //check controller and action BypassValidation value
        if (BypassValidation || 
            actionAttributes.Count > 0 && actionAttributes.Any(x => x.BypassValidation))
        {
            return true;
        }
        else
        {
          //return false if user is unverified
        }

        return base.IsAuthorized(actionContext);
    }
 }

Ответ 2

Слишком поздно, но для других пользователей с аналогичными проблемами: в Web API 2 вы можете переопределить все предыдущие атрибуты авторизации (глобальные фильтры авторизации, атрибуты авторизации контроллера и т.д.), используя "OverrideAuthorization", а затем просто используйте атрибут Authorize, без указания роли. По умолчанию атрибут Authorize используется для проверки подлинности пользователя.

В этом случае:

[YourCustomAuthorize]
public class UserProfileController : ApiController
{
    [OverrideAuthorization]
    [Authorize]
    public bool Verify(string verificationCode)
    {
    // TODO
    }
}