2010-10-20 18 views
11

MSDN dice explícitamente que debe hacer redirección 401, pero me estoy poniendo un redireccionamiento 302 en FF, y esto está causando problemas en las solicitudes de AJAX como el devuelto el estado es 200 (desde la página redirigida).ASP.NET MVC Autorizar Atributo hace una redirección 302 cuando el usuario no está autorizado

http://msdn.microsoft.com/en-us/library/system.web.mvc.authorizeattribute.aspx

he encontrado a otra persona con el mismo problema: http://blog.nvise.com/?p=26

Cualquier otra solución, además de su?

Respuesta

9

El atributo Autorizar hace devolver un Http 401 Respuesta no autorizada. Por desgracia, sin embargo, si usted tiene FormsAuthentication habilitado, el 401 es interceptada por el FormsAuthenticationModule que luego realiza una redirección a la página de inicio de sesión - que luego devuelve un HTTP 200 (y la página de inicio de sesión) de nuevo a su petición Ajax.

La mejor alternativa es escribir su propio atributo de autorización, y luego, si se obtiene una solicitud no autenticado que es también una petición Ajax, devuelve un código de estado HTTP diferente - por ejemplo 403 - que no se ha caído en la FormsAuthenticationModule y que pueda atrapa en tu método Ajax.

12

me gusta mucho esta solución. Al cambiar la respuesta 302 de las peticiones ajax a un 401 que le permite configurar el Ajax en el lado del cliente para controlar cualquier solicitud de ajax en busca de un 401 y si encuentra uno para redirigir a la página de inicio de sesión. Muy simple y efectivo.

Global.asax: Código lateral

protected void Application_EndRequest() 
{ 
    if (Context.Response.StatusCode == 302 && 
     Context.Request.Headers["X-Requested-With"] == "XMLHttpRequest") 
    { 
     Context.Response.Clear(); 
     Context.Response.StatusCode = 401; 
    } 
} 

Cliente:

$(function() { 
     $.ajaxSetup({ 
     statusCode: { 
      401: function() { 
      location.href = '/Logon.aspx?ReturnUrl=' + location.pathname; 
      } 
     } 
     }); 
    }); 
+0

El código funcionó perfectamente para mí. Gracias. – njr101

+3

Esta es una mala práctica, ya que todas las solicitudes se deben incluir en EndRequest, incluidos todos los archivos estáticos. –

+1

Es tan triste que la "mejor" forma de tratar esto implica secuestrar TODOS ajax 302s –

2

que implementa mi propio atributo autorizar costumbre que heredó de AuthorizeAttribute y se encontró con el mismo problema.

Luego descubrí que desde .Net 4.5 hay una solución a esto - se puede suprimir la redirección de la siguiente manera:

context.HttpContext.Response.SuppressFormsAuthenticationRedirect = true; 

A continuación, la respuesta será un 401 - No autorizado, junto con el Desafío de autenticación básica de HTTP

Más información here

+0

Esta debería ser la respuesta aceptada. – icesar

0

Si está utilizando una aplicación Web ASP.NET MVC 5 ir a App_Start ->Startup.Auth.cs. Compruebe si está habilitado app.UseCookieAuthentication y ver si se ajusta a CookieAuthenticationOptionsLoginPath = new PathString("/Login"), o similar. Si elimina este parámetro 401 se detendrá la redirección.

Descripción para LoginPath:

La propiedad LoginPath informa al middleware que se debe cambiar un código de estado no autorizado saliente 401 en una redirección 302 en el camino de acceso dada . La url corriente que genera el 401 se añade a la LoginPath como un parámetro de cadena de consulta nombrada por el ReturnUrlParameter.Una vez que una solicitud al LoginPath concede una nueva identidad de inicio de sesión , el valor ReturnUrlParameter se utiliza para redireccionar el navegador a la url que causó el código de estado no autorizado original . Si LoginPath es nulo o está vacío, el middleware no se verá para códigos de estado 401 no autorizados, y no redirigirá automáticamente cuando se produce un inicio de sesión.

Cuestiones relacionadas