2009-05-15 7 views
5

Beim Aufbau eines Content-Management-System, das jQuery AJAX in seine GUI integriert habe, bin ich auf eine Hürde gestoßen. Es scheint, dass einige Kunden zu lange darüber nachdenken, was sie schreiben werden, und deshalb protokolliert die Server-Sitzung sie, natürlich das Netz, von dem sie keine Ahnung haben. Wenn sie versuchen, die Änderungen zu übermitteln, verwende ich einen Ajax-Aufruf an den Server, um die Daten zu speichern.Überprüfung auf HTTP-Autorisierung in mvc vor Ajax Formular Post

Was ich als nächstes erwarten würde ist, dass die MVC-Server-Anwendung einen "401 Unauthorized" Status zurückgeben würde. Ich könnte dann mein jquery ajax Objekt bekommen, um den Benutzer zu bitten, sich anzumelden und die Änderungen erneut zu senden, sobald der Benutzer autorisiert wurde.

Was jedoch tatsächlich von der MVC-Anwendung zurückgegeben wird, ist ein "302 Found" -Status und eine Weiterleitungs-URL zu meiner Anmeldeseite. Die Seite des Anmeldeformulars gibt einen Statuscode "200 OK" zurück, und das Objekt jquery ajax ruft das Erfolgsereignis auf, das dem Benutzer mitteilt, dass alles erfolgreich war, da dies die MVC-Anwendung angibt.

Gibt es eine Möglichkeit für mich, die MVC-Anwendung so zu spielen, wie ich denke, dass ich meine jquery ajax-Ereignisse ändern muss, um die Anmeldeseite zu erkennen?

Update:

I Reflektor verwendet habe einen Blick in das MVC-Code zu haben, und das Autorisieren Attribut, geben Sie den Code ein NotAuthorizedResult für das unten ist (0x191 = 401)

public override void ExecuteResult(ControllerContext context) 
{ 
    if (context == null) 
    { 
     throw new ArgumentNullException("context"); 
    } 
    context.HttpContext.Response.StatusCode = 0x191; 
} 

Ich denke, dass die Forms Authorization HttpModule die 401 sieht und die Umleitung erzwingt.

Antwort

6

Sie so etwas wie dies versuchen könnte:

void context_EndRequest(object sender, EventArgs e) 
    { 
     var app = sender as HttpApplication; 
     var response = app.Response; 
     var request = app.Request; 

     if ((response.StatusCode == 302) && IsAjaxRequest(request)) 
      response.StatusCode = 401; 
    } 

in einem Httpmodule, wird es nach dem FormsAuth Modul in Folge wird so den Statuscode korrigieren. Nicht schön, aber effektiv.

+0

In .Net 4.0 (vielleicht auch andere Versionen, weiß ich nicht), führt FormsAuthentication die Umleitung im EndRequest-Handler.Ich habe festgestellt, dass FormsAuth die Antwort nicht verarbeitet hat, wenn ich EndRequest verwendet habe, aber das PreSendRequestHeaders-Ereignis funktioniert viel besser (kommt nach EndRequest). Danke für diesen tollen Beitrag. – womp

5

Ich mag diese Lösung wirklich. Durch Ändern der 302-Antwort auf Ajax-Anfragen zu einem 401 ermöglicht es Ihnen, Ihren Ajax auf der Client-Seite einzurichten, um jegliche Ajax-Anfrage zu überwachen, die nach einem 401 sucht, und wenn er einen zur Weiterleitung auf die Anmeldeseite findet. Sehr einfach und effektiv.

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 Side-Code:

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

Ich habe festgestellt, dass ein leichter Ansatz einfach ist, einen benutzerdefinierten HTTP-Header auf der Login-Seite hinzufügen und überprüfen für das Vorhandensein dieser in der AJAX-Erfolg Rückruf.

Ie. in dem LoginController (dies ist ein MVC-Projekt, aber das gleiche Prinzip sollte für andere ASP.NET Lösungen anwenden):

public ActionResult Login(string returnUrl = "") 
{ 
    Response.AddHeader("X-Unauthorized", "true"); 
    ... 

Und dann in dem Client-Seite AJAX-Handler:

success: function(data, textStatus, jqXhr) 
{ 
    if (jqXhr.getResponseHeader("X-Unauthorized")) 
    { 
     ... 

Dies funktioniert für mich zumindest.

Verwandte Themen