MVC 4 AuthorizEatTribe.HandleunautHoredIredRequest ViewResult - Infinite Loop
-
21-12-2019 - |
Pregunta
He pasado por mi código un millón de veces y no puedo encontrar un problema con mi implementación.
en AuthorizEatTribe personalizado Sobrescribir 2 Métodos
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (!httpContext.Request.IsAuthenticated)
return false;
var routeData = httpContext.Request.RequestContext.RouteData;
var ctrl = routeData.Values["controller"].ToString();
var action = routeData.Values["action"].ToString();
var user = httpContext.User.Identity.Name;
_logger.Info("[logging all the details]");
return ctrl == "SomeController";
}
protected override void HandleUnauthorizedRequest(AuthorizationContext ctx)
{
ctx.Result = new ViewResult { ViewName = "Unauthorized" };
// base.HandleUnauthorizedRequest(ctx);
}
La lógica de autorización se burla para devolver Falso solo en un controlador específico, y he pasado a través de esto para verificar que funcione correctamente.
El código anterior causará un bucle infinito.En mi registro puedo ver esa línea golpeada 666 veces (coincidencia?) ..
Si llamo a la base de la Base.HandleunautHorIdedRequest (CTX), todo lo que recibo es una página en blanco.así que reflexioné lo que hace la base, y es esto
filterContext.Result = new HttpUnauthorizedResult();
Entonces esto explica por qué hace una página en blanco en lugar de redirigir a no autorizados.cshtml.De lo que no estoy seguro, es por qué entra en un bucle infinito si no llamo a la base.
p.s.
He verificado que si pongo la vista incorrecta no autorizada, se equivocará (pero aún se cuelga indefinidamente)
System.InvalidOperationException: The view 'Unauthorized11' or its master was not found or no view engine supports the searched locations
Solución
Aquí está la implementación en la que terminé yendo y está funcionando muy bien.
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
// this is overriden for kendo menus to hide
var ctrl = filterContext.RequestContext.RouteData.GetRequiredString("controller");
var action = filterContext.ActionDescriptor.ActionName;
[custom authorization logic on action/ctrl]
// useful to determine if it's authorizing current controller path or menu links
var path = filterContext.HttpContext.Request.PhysicalPath;
_authorizingCurrentPath = path.Contains(ctrl) || path.EndsWith("WebUI") ;
if (userAuth < requiredAuth)
HandleUnauthorizedRequest(filterContext);
}
protected override void HandleUnauthorizedRequest(AuthorizationContext ctx)
{
if (!ctx.HttpContext.User.Identity.IsAuthenticated)
base.HandleUnauthorizedRequest(ctx);
else {
if (_authorizingCurrentPath) {
// handle controller access
ctx.Result = new ViewResult { ViewName = "Unauthorized" };
ctx.HttpContext.Response.StatusCode = 403;
}
else {
// handle menu links
ctx.Result = new HttpUnauthorizedResult();
ctx.HttpContext.Response.StatusCode = 403;
}
}
}
Otros consejos
La implementación predeterminada de AutorizEatTribute establece la respuesta en el contexto de acción, al no llamar a la base, la respuesta nunca se establece, lo que hace que el filtro repita el proceso de autorización hasta que se establezca una respuesta (de ahí el bucle infinito).
Puede ver esta lógica en la AuthorizationFilterAttribute clase que autorizatetribute deriva de.