2012-04-05 4 views
1

Ich habe ein seltsames Problem mit der Formularauthentifizierung. Ich habe meine eigenen benutzerdefinierten Prinzipal- und Identitätsklassen, und nach der Anmeldung setze ich HttpContext.Current.User auf diesen Principal und speichere ihn im Cache (HttpContext.Current.Cache). Es scheint, dass nach einiger Zeit das seltsame Verhalten beginnt. Dies ist mein AuthenticateRequest-Handler:Asp.net Formularauthentifizierung - Hauptänderungen?

protected void Application_AuthenticateRequest(object sender, EventArgs e) { 
    string userName; 

    var formAuthCookie = HttpContext.Current.Request.Cookies[ FormsAuthentication.FormsCookieName ]; 
    var isAuthenticated = HttpContext.Current.Request.IsAuthenticated; 

    if (isAuthenticated || formAuthCookie != null) { 
     if (!isAuthenticated) { 
      var ticket = FormsAuthentication.Decrypt(formAuthCookie.Value); 
      userName = ticket.Name; 
     } 
     else { 
      userName = HttpContext.Current.User.Identity.Name; 
     } 

     var prin = (IPrincipal)HttpContext.Current.Cache[ userName ]; 

     if (prin != null) { 
      HttpContext.Current.User = prin; 
     } 
    } 
} 

Das funktioniert immer gut; Der benutzerdefinierte Prinzipal wird aus dem Cache abgerufen und ordnungsgemäß in den Benutzer des aktuellen Kontexts versetzt.

Das Problem ist, dass, wenn ich zum Laden der Seite komme, die Page.User -Eigenschaft eine GenericPrincipal (ohne Rollen) und eine FormsIdentity hat. Ich habe keine Ahnung, wo das passiert. Natürlich funktioniert die Seite dann nicht, da sich der Benutzer nicht in der richtigen Rolle befindet, obwohl FormsAuth sie in eine Seite mit eingeschränkter Rolle lenkt.

Irgendwelche Ideen, warum das Prinzip, das ich im AuthenticateRequest-Handler gesetzt habe, ersetzt wird?

+0

Sie erkennen, dass FormsAuthentication wird Cookies in Ihrem Browser, während Cache AppDomain basiert, jedes Mal wenn die Anwendungsdomäne Recyles bedeutet, alles, was es verloren geht ... –

+0

Die App-Pool ist nicht sein recycelt. Eigentlich hast du mich daran erinnert, dass das App-Pool das Problem anscheinend ein wenig korrigiert. Der Cookie wird so eingestellt, dass er gleichzeitig mit der Sitzung abläuft. Das Problem ist nicht, dass der Cache verloren geht, da ich den obigen Code verfolgen kann und sehe, wie der richtige Principal rausgeholt wird und buchstäblich Sekunden später in page_load habe ich einen anderen Principal. – Andy

+0

Sie sollten die Sitzung niemals so einstellen, dass sie gleichzeitig mit dem Formular-Authentifizierungs-Cookie abläuft. http://completedevelopment.blogspot.com/2009/12/caution-with-using-sessiontimeout-and.html –

Antwort

-1

Versuchen Sie stattdessen:

var formAuthCookie = Context.Request.Cookies[ FormsAuthentication.FormsCookieName ]; 
var isAuthenticated = Context.Request.IsAuthenticated; 

if (isAuthenticated || formAuthCookie != null) { 
    if (!isAuthenticated) { 
     var ticket = FormsAuthentication.Decrypt(formAuthCookie.Value); 
     userName = ticket.Name; 
    } 
    else { 
     userName = Context.User.Identity.Name; 
    } 

    var prin = (IPrincipal)Context.Cache[ userName ]; 

    if (prin != null) { 
     Context.User = prin; 
    } 
} 
+0

Können Sie die Unterschiede zwischen diesem und dem, was ich habe, hervorheben? – Andy

+0

@Andy - Es ist ein kleiner Code-Block, die Änderungen sind offensichtlich. Sie ändern nur HttpContext.Current. * zu Context. * –

+0

Dies ist kein Unterschied. – bang