2010-01-20 4 views
25

Ich verwende Formularauthentifizierung und sende eine Aajx-Anfrage an den Server zur Authentifizierung. Basierend auf dem Json-Ergebnis entscheidet der Kunde, wohin er gehen und was zu tun ist. Das ist der Grund, warum ich FormsAuthentication.RedirectFromLoginPage nicht verwende, um die AJAX/JSON-Antwort nicht zu stören.Wie wird Request.IsAuthenticated auf "True" festgelegt, wenn FormsAuthentication.RedirectFromLoginPage nicht verwendet wird?

In diesem Fall gibt Request.IsAuthenticated false zurück, auch nachdem der Benutzer mit Membership.ValidateUser validiert wurde. Dann habe ich das Cookie mit

FormsAuthentication.SetAuthCookie(username, false); 

Obwohl der zweite Parameter, dauerhaftes Cookie, falsch ist, das Cookie über Browser-Sitzungen noch gültig ist.

Gibt es eine Idee, wie Request.IsAuthenticated funktioniert, ohne FormsAuthentication.RedirectFromLoginPage zu verwenden?

+0

Es ist möglich, Sie sind nicht das Cookie korrekt mit Hilfe eines AJAX-Request Einstellung ... – Jason

+0

Haben Sie die Msdn Anweisungen unter http zu folgen versucht: //msdn.microsoft.com/en-us/library/bb398896.aspx? –

+0

Dies ist besonders problematisch, wenn Sie versuchen, ein fälschungssicheres Token in Ihrer Ajax-Authentifizierungsanforderung (z. B. einem SPA) zu generieren und zurückzugeben. Asp.Net wird das Token für einen "" Benutzer generieren, da es annimmt, dass niemand gerade authentifiziert ist. – SeeNoWeevil

Antwort

22

Sie müssen den aktuellen Sicherheitsprinzipal für die Anforderung aktualisieren. Wenn Sie Response. Redirect(...) aufrufen, wird eine neue Anforderung ausgeführt, und der Sicherheitsprinzipal wird neu initialisiert, und Request.IsAuthenticated gibt in Ihrem Fall "true" zurück. FormsAuthentication.RedirectFromLoginPage intern ruft Response. Redirect(...). Sie können manuell den Sicherheitsprinzipal für die aktuelle Anforderung wie folgt verlängern:

public void RenewCurrentUser() 
{ 
    System.Web.HttpCookie authCookie = 
     System.Web.HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName]; 
    if (authCookie != null) 
    { 
     FormsAuthenticationTicket authTicket = null; 
     authTicket = FormsAuthentication.Decrypt(authCookie.Value); 

     if (authTicket != null && !authTicket.Expired) 
     { 
      FormsAuthenticationTicket newAuthTicket = authTicket; 

      if (FormsAuthentication.SlidingExpiration) 
      { 
       newAuthTicket = FormsAuthentication.RenewTicketIfOld(authTicket); 
      } 
      string userData = newAuthTicket.UserData; 
      string[] roles = userData.Split(','); 

      System.Web.HttpContext.Current.User = 
       new System.Security.Principal.GenericPrincipal(new FormsIdentity(newAuthTicket), roles); 
     } 
    } 
} 
+0

Eine manuelle Verlängerung ist nicht erforderlich (insbesondere für GenericPrincipal und FormsIdentity), und die Anmeldeinformationen sollten sich während einer Anfrage nicht ändern, weshalb der Cookie zur Antwort hinzugefügt wird und dann ein vollständig neuer Antwort-/Anforderungslebenszyklus ausgeführt wird. Bei der nächsten Anfrage wird der von FormsAuthentication.SetAuthCookie() erstellte Cookie übernommen. –

+4

Natürlich kann diese Methode als Hack betrachtet werden, da sie nicht dem normalen Formularauthentifizierungsablauf folgt. Es kann jedoch nützlich sein, wenn Sie prüfen möchten, ob der Benutzer in derselben Anfrage authentifiziert ist, an der die Authentifizierung beteiligt ist. –

+1

Manchmal, obwohl ein Hack ist, was Sie brauchen - Ich habe versucht, Dinge "den richtigen Weg" zu tun und eine Umleitung zu zwingen, und in einen richtigen Zustand mit anderen Systemen umgeleitet werden :( –

20

FormsAuthentication.SetAuthCookie

Methode ein Authentifizierungs Ticket erstellt für die Benutzername geliefert und fügt sich die Sammlung von Cookies die Antwort oder die URL, wenn Sie mit cookieless Authentifizierung verwenden.

Ref: msdn

Werfen Sie einen Blick auf die Forms Authentication Control Flow. Der Authentifizierungscookie wird auf die Antwortcookie-Sammlung festgelegt und sollte auf der HTTP-Protokollebene beobachtbar sein (z. B. FireCookie oder Fiddler2, um dies zu überprüfen).

Die Mitgliedschaft verifiziert nur einen Benutzernamen/ein Passwort. Weder die Mitgliedschaft noch SetAuthCookie() werden die aktuelle Anfrage ändern. Sie erwarten, das Cookie zurück an den Aufrufer zu senden, und die next Anfrage ist, wenn die Eigenschaften wie IsAuthenticated wird True zurückgegeben.

Beachten Sie, dass diese automatische Prozesse außer Kraft setzen und erweitern können benutzerdefinierte mit IIdentity und IPrincipal und in die Authentifizierungsereignisse Haken, wenn Sie benötigen.

haben auch einen Blick auf Using Forms Authentication with ASP.NET AJAX

+0

Dies ist eine gute Antwort. – Greg

+1

+1 für die Formularauthentifizierung Control Flow Referenz. – CGK

+0

Ich habe Fiddler verwendet, um Cookies anzuzeigen in Anfrage und Antwort –

2

Umleiten nach einer POST beste Praxis ist, und sollte die richtige Lösung in Betracht gezogen werden. In einigen Fällen möchten Sie möglicherweise noch herausfinden, ob ein Benutzer im Rahmen der Authentifizierungsanforderung authentifiziert wurde (z. B. wenn Sie nach Durchführung der Authentifizierung zusätzliche Logik ausführen, die für andere Anforderungen freigegeben ist).

In diesem Fall können Sie den Wert von Request zurücksetzen.IsAuthenticated mit dem folgenden Code:

// set the forms auth cookie 
FormsAuthentication.SetAuthCookie(username, createPersistentCookie); 

// reset request.isauthenticated 
var authCookie = System.Web.HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName]; 
if (authCookie != null) 
{ 
    FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value); 
    if (authTicket != null && !authTicket.Expired) 
    { 
     var roles = authTicket.UserData.Split(','); 
     System.Web.HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(new FormsIdentity(authTicket), roles); 
    } 
} 

Siehe Beitrag hier: http://abadjimarinov.net/blog/2010/01/24/RenewUserInTheSameRequestInAspdotNET.xhtml

Verwandte Themen