asp.net-mvc - origin - enable cors web config
Propiedades de atributo autorizar web personalizado de Api (2)
Estoy tratando de extender el atributo autorizar de Web Api predeterminado para permitir que los usuarios autenticados tengan acceso a un conjunto de acciones aunque no estén registradas en la aplicación (por ejemplo, no tienen un rol).
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);
}
}
Y está siendo usado así:
[AuthorizeVerifiedUsers]
public class UserProfileController : ApiController
{
[AuthorizeVerifiedUsers(BypassValidation = true)]
public bool Verify(string verificationCode)
{}
}
Hasta ahora, esta acción es la única que usa BypassValidation = true.
El problema surge porque la propiedad BypassValidation es falsa para la acción aunque la ventana de depuración, utilizada en la propiedad BypassValidation, muestra lo siguiente:
set: 26833123 True set: 39602703 True get: 43424763 False get: 43424763 False get: 43424763 False // llamada que debería tener "True" ...
Noté dos cosas:
- El TypeId (el identificador único para el atributo) es diferente entre las llamadas que tienen BypassValidation = true y las que tienen BypassValidation = false.
- El ID ''43424763'' no tiene un conjunto correspondiente
¿Algunas ideas?
Gracias de antemano, Joao
La forma en que funciona la API web es que el atributo autorizar se llama para el ámbito principal, en este caso el controlador, y la anulación (atributo de autorizar en la acción) debe hacerse manualmente (corríjame si me equivoco).
Por lo tanto, una solución podría ser similar a la siguiente:
public class AuthorizeVerifiedUsersAttribute : AuthorizeAttribute
{
(...)
protected override bool IsAuthorized(HttpActionContext actionContext)
{
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
//retrieve controller action''s 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);
}
}
Un poco tarde, pero para otros usuarios con problemas similares: en Web API 2 puede anular todos los atributos de autorización previos (filtros de autorización global, atributos de autorización del controlador, etc.) usando "OverrideAuthorization" y luego usar el atributo Authorize, sin especificar el papel. El comportamiento predeterminado del atributo Autorizar es solo para verificar si el usuario está autenticado.
En este caso:
[YourCustomAuthorize]
public class UserProfileController : ApiController
{
[OverrideAuthorization]
[Authorize]
public bool Verify(string verificationCode)
{
// TODO
}
}