working not allowanonymous allow asp.net-mvc authentication attributes asp.net-web-api

asp.net mvc - not - AllowAnonymous no funciona con Custom AuthorizationAttribute



allow anonymous c# (4)

Debo utilizar una versión diferente del .NET framework o web api pero espero que esto ayude a alguien:

bool skipAuthorization = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any() || actionContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any(); if (skipAuthorization) { return; }

Esto me ha dejado perplejo por un tiempo. Aparentemente, ninguna de las situaciones similares más comunes parece aplicarse aquí. Probablemente me haya perdido algo obvio, pero no puedo verlo.

En mi aplicación web Mvc, utilizo los atributos Authorize y AllowAnonymous de tal manera que debe abrir explícitamente una acción como públicamente disponible en lugar de bloquear las áreas seguras del sitio. Yo prefiero ese enfoque. Sin embargo, no puedo obtener el mismo comportamiento en mi WebAPI.

He escrito un atributo de autorización personalizado que hereda de System.Web.Http.AuthorizeAttribute con lo siguiente:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] public class MyAuthorizationAttribute : System.Web.Http.AuthorizeAttribute

Tengo esto registrado como un filtro:

public static void RegisterHttpFilters(HttpFilterCollection filters) { filters.Add(new MyAuthorizationAttribute()); }

Todo esto funciona como se esperaba, las acciones ya no están disponibles sin credenciales. El problema es que ahora el siguiente método no permitirá que el atributo AllowAnonymous lo haga:

[System.Web.Http.AllowAnonymous] public class HomeController : ApiController { [GET("/"), System.Web.Http.HttpGet] public Link[] Index() { return new Link[] { new SelfLink(Request.RequestUri.AbsoluteUri, "api-root"), new Link(LinkRelConstants.AuthorizationEndpoint, "OAuth/Authorize/", "authenticate"), new Link(LinkRelConstants.AuthorizationTokenEndpoint , "OAuth/Tokens/", "auth-token-endpoint") }; } }

El escenario más común parece ser confundir los dos atributos Authorize / AllowAnonymous. System.Web.Mvc es para aplicaciones web y System.Web.Http es para WebAPI (como yo lo entiendo de todos modos).

Los dos atributos que estoy usando son del mismo espacio de nombres: System.Web.Http. Supuse que esto solo heredaría la funcionalidad base y me permitiría insertar el código que necesito en el método OnAuthotize.

De acuerdo con la documentación, el atributo AllowAnonymous funciona dentro del método OnAuthorize al que llamo inmediatamente:

public override void OnAuthorization(HttpActionContext actionContext) { base.OnAuthorization(actionContext);

Cualquier pensamiento sería realmente apreciado.

¿Alguien ha encontrado este problema antes y ha encontrado la causa raíz?


En AuthorizeAttribute hay el siguiente código:

private static bool SkipAuthorization(HttpActionContext actionContext) { Contract.Assert(actionContext != null); return actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any() || actionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any(); }

Incluya este método en su clase AuthorizeAttribute y agregue lo siguiente al principio de su método OnAuthorization para omitir la autorización si se encuentran atributos AllowAnonymous:

if (SkipAuthorization(actionContext)) return;


Usando C # 6.0 Cree una clase estática que amplíe ActionExecutingContext.

public static class AuthorizationContextExtensions { public static bool SkipAuthorization(this ActionExecutingContext filterContext) { Contract.Assert(filterContext != null); return filterContext.ActionDescriptor.GetCustomAttributes(typeof(AllowAnonymousAttribute), true).Any()|| filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(typeof(AllowAnonymousAttribute), true).Any(); } }

Ahora su override filterContext podrá llamar al método de extensión, solo asegúrese de que estén en el mismo espacio de nombres, o incluya la instrucción de uso apropiada.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] public class AuthorizeCustomAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { if (filterContext.SkipAuthorization()) return;// CALL EXTENSION METHOD /*NOW DO YOUR LOGIC FOR NON ANON ACCESS*/ } }


ASP.NET MVC 4:

bool skipAuthorization = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) || filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true);

o

private static bool SkipAuthorization(AuthorizationContext filterContext) { Contract.Assert(filterContext != null); return filterContext.ActionDescriptor.GetCustomAttributes(typeof(AllowAnonymousAttribute), true).Any() || filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(typeof(AllowAnonymousAttribute), true).Any(); }

Soruce: http://weblogs.asp.net/jongalloway/asp-net-mvc-authentication-global-authentication-and-allow-anonymous