¿Cómo puedo desarrollar un AuthorizeAttribute personalizado que acepte un inicio de sesión O un token?

En mi aplicación MVC 5, decoro mis controladores de la siguiente manera:

[Authorize] public class Controller { .. 

Sin embargo, un requisito que tengo es usar un token para autorizar una acción sin tener que ir a la pantalla de inicio de sesión. es decir: http://{website}/Action?token={/* token for this user */}

Por lo tanto, ¿cómo puedo desarrollar un AuthorizeAttribute personalizado que acepte un inicio de sesión (comportamiento predeterminado) O un token (comportamiento personalizado, requerido)?

En otras palabras, si uso http://{website}/Action , me redireccionaría a la pantalla de inicio de sesión (si no estoy autorizado), pero si uso http://{website}/Action?token={/* token for this user */} , estaría autorizado y redirigido a dicha acción.


[TokenAuthorize]

 public class TokenAuthorize : AuthorizeAttribute { private const string SecureToken = "token"; public override void OnAuthorization(AuthorizationContext filterContext) { if (Authorize(filterContext)) { return; } HandleUnauthorizedRequest(filterContext); } private bool Authorize(AuthorizationContext actionContext) { try { HttpRequestBase request = actionContext.RequestContext.HttpContext.Request; string token = request.Params[SecureToken]; return SecurityManager.IsTokenValid(token); } catch (Exception) { return false; } } } 

Si decoro mis controladores con:

 [Authorize] [TokenAuthorize] public class Controller { .. 

Se procesa como Authorize AND TokenAuthorize (1) . Necesito desarrollar una manera de procesar, como Authorize O Authorize TokenAuthorize

¿Qué hay de decorar solo con TokenAuthorize y luego volver al comportamiento predeterminado si no existe token?

TokenAuthorize.cs

 protected override bool AuthorizeCore(HttpContextBase httpContext) { bool isTokenAuthorized = HasValidToken(...); if(isTokenAuthorized) return true; bool isDefaultAuthorized = base.AuthorizeCore(httpContext); if(isDefaultAuthorized) return true; return false; } 

MyController.cs

 [TokenAuthorize] public class MyController { ... } 

La respuesta de Shoe me llevó por el camino correcto.

Implementé su sugerencia e hice lo siguiente en mi función Authorize :

 private bool Authorize(AuthorizationContext actionContext) { try { HttpContextBase context = actionContext.RequestContext.HttpContext; string token = context.Request.Params[SecurityToken]; bool isTokenAuthorized = SecurityManager.IsTokenValid(token); if (isTokenAuthorized) return true; bool isDefaultAuthorized = AuthorizeCore(context); return isDefaultAuthorized; } catch (Exception) { return false; } } 

Decorando solo con [TokenAuthorize] , puedo autorizar una acción a través del inicio de sesión (predeterminado) O mediante un token.