2010-10-20 14 views
11

MSDN dice esplicitamente che deve eseguire il reindirizzamento 401, ma sto ricevendo un reindirizzamento 302 su FF e questo sta causando problemi nelle richieste AJAX come restituito lo stato è 200 (dalla pagina reindirizzata).ASP.NET MVC Autorizza attributo esegue un reindirizzamento 302 quando l'utente non è autorizzato

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

ho trovato qualcun altro con lo stesso problema: http://blog.nvise.com/?p=26

Qualsiasi altra soluzione, oltre alla sua?

risposta

9

L'attributo Authorize fa restituisce una risposta 401 non autorizzata. Sfortunatamente, tuttavia, se si dispone di FormsAuthentication, il 401 viene intercettato da FormsAuthenticationModule che esegue quindi un reindirizzamento alla pagina di accesso, che restituisce un Http 200 (e la pagina di accesso) alla richiesta ajax.

L'alternativa migliore è scrivere il proprio attributo di autorizzazione, e quindi se si ottiene una richiesta non autenticata che è anche una richiesta Ajax, restituire un diverso codice di stato Http - ad esempio 403 - che non viene catturato dal formsAuthenticationModule e si può prendi il tuo metodo Ajax.

12

Mi piace molto questa soluzione. Modificando la risposta 302 su richieste Ajax su un 401, è possibile impostare l'ajax sul lato client per monitorare qualsiasi richiesta Ajax che cerca un 401 e se ne trova uno per reindirizzare alla pagina di accesso. Molto semplice ed efficace.

Global.asax:

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

client codice lato:

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

Il codice ha funzionato perfettamente per me. Grazie. – njr101

+3

Questa è una cattiva pratica, perché tutte le richieste devono essere inserite in EndRequest, inclusi tutti i file statici. –

+1

È così triste che il modo "migliore" per gestire questo problema è il dirottamento di ALL ajax 302s –

2

Ho implementato il mio attributo Autorizza personalizzato che ha ereditato da AuthorizeAttribute e corse nello stesso problema.

poi ho scoperto che da quando Net 4.5 c'è una soluzione a questo - è possibile sopprimere il reindirizzamento nel seguente modo:

context.HttpContext.Response.SuppressFormsAuthenticationRedirect = true; 

allora la risposta sarà un 401 - non autorizzata, insieme con il Sfida di autenticazione di base HTTP.

Maggiori informazioni here

+0

Questa dovrebbe essere la risposta accettata. – icesar

0

Se si utilizza un ASP.NET MVC 5 Web Application andare App_Start ->Startup.Auth.cs. Verificare se app.UseCookieAuthentication è abilitato e vedere se CookieAuthenticationOptions è impostato su LoginPath = new PathString("/Login"), o simile. Se si rimuove questo parametro, 401 interromperà il reindirizzamento.

Descrizione per LoginPath:

La proprietà LoginPath informa il middleware che dovrebbe cambiare un codice di stato non autorizzato in uscita 401 in un reindirizzamento 302 sul dato percorso di accesso. L'url corrente che ha generato il 401 viene aggiunto a il LoginPath come parametro della stringa di query nominato dal parametro ReturnUrlParametro .Quando una richiesta al LoginPath concede una nuova identità SignIn , il valore ReturnUrlParameter viene utilizzato per reindirizzare il browser all'url che ha causato il codice di origine non autorizzato dello stato . Se LoginPath è nullo o vuoto, il middleware non vedrà per 401 codici di stato non autorizzati e non reindirizzerà automaticamente quando si verifica un accesso.

Problemi correlati