Свойства настраиваемого атрибута веб-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
}
}