Forms-Authentifizierung und die Authentifizierung cookie nicht beibehalten
bewusst, dass es eine Menge von Fragen, welche Formen der Authentifizierung und der Persistenz von cookies, aber nachdem er verbrachte die meiste Zeit des Tages Graben wir um, ich bin immer noch Schwierigkeiten.
Mein Problem
Arbeite ich an einer web-app (VS2010, aber webapp ist f/w 3,5), die beschränkt den Zugriff auf bestimmte Teile der app auf authentifizierte Benutzer (während andere Teile offen sind). Mein problem ist, dass meine cookies nicht angezeigt werden beibehalten, nachdem ich den browser schließen.
Mein Ansatz
Ich geschrieben habe ein einfaches login.aspx-Seite, die konfiguriert ist im web.config wie folgt:
<authentication mode="Forms">
...und die einzelnen Seiten Verhalten deklariert sind, etwa so:
<location path="ClientManageAccount.aspx">
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</location>
...was funktioniert gut in jeder Hinsicht, AUßER für diese cookie-Spielereien...
Erstelle ich das authentication cookie manuell, sobald ich authentifiziert haben, mein Benutzer-login & Passwort für die Datenbank (die funktioniert einwandfrei) in der Anmeldung.aspx-Seite. Wenn der Benutzer wählt das "eingeloggt bleiben" aktivieren, wird das cookie erzeugten mit dieser Methode:
private void GenerateAuthenticationCookie(int expiryInMinutes, Guid userGuid)
{
DateTime cookieExpiration = DateTime.Now.AddMinutes(expiryInMinutes); //change to months for production
var authenticationTicket =
new FormsAuthenticationTicket(
2,
userGuid.ToString(),
DateTime.Now,
cookieExpiration,
true,
string.Empty,
FormsAuthentication.FormsCookiePath);
//ticket must be encrypted
string encryptedTicket = FormsAuthentication.Encrypt(authenticationTicket);
//create cookie to contain encrypted auth ticket
var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
authCookie.Expires = authenticationTicket.Expiration;
authCookie.Path = FormsAuthentication.FormsCookiePath;
//clear out existing cookie for good measure (probably overkill) then add
HttpContext.Current.Response.Cookies.Remove(FormsAuthentication.FormsCookieName);
HttpContext.Current.Response.Cookies.Add(authCookie);
}
Das Ziel hier ist, dass ich speichern Sie eine Benutzer-Guid in das auth-cookie, die ich dann verwenden, um die Wiederherstellung eine user-Objekt in die session (dies ist auch in der login.aspx-Seite, und mein denken ist, ich würde gerne zupfen Sie die Benutzer-guid aus dem auth-cookie, die ich erstellt habe, und es verwenden, um Sachen, die entsprechenden Benutzer-Datensatz in der session und eine Umleitung auf die gewünschte Seite):
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
TryAutoLogin();
}
}
private void TryAutoLogin()
{
HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(FormsAuthentication.FormsCookieName);
if (cookie != null)
{
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);
if (ticket != null)
{
if (ticket.Name.Length > 0)
{
try
{
Guid userGuid = new Guid(ticket.Name);
KUser user = UserFunctions.GetUserFromUserGuid(userGuid);
if (user != null) Session["User"] = user;
FormsAuthentication.RedirectFromLoginPage(userGuid.ToString(), true);
}
catch (Exception anyException)
{
//don't do anything for now - do something smart later :-) }
}
}
}
}
Schließlich, hier ist der code für den login button auf meiner login.aspx-Seite:
protected void Submit_OnClick(object sender, EventArgs e)
{
long userId = 0;
UserAuthenticationStatus status;
status = (UserAuthenticationStatus)UserFunctions.UserAuthenticates(EmailAddress.Text, Password.Text, ref userId);
switch (status)
{
case UserAuthenticationStatus.Authenticated:
//email address and password match, account ok, so log this user in
KUser user = UserFunctions.GetUser(userId);
Session["User"] = user;
if (ChkRememberMe.Checked)
{
GenerateAuthenticationCookie(15, user.UserGuid); //15 minutes
FormsAuthentication.RedirectFromLoginPage(user.UserGuid.ToString(), true);
}
else
{
FormsAuthentication.RedirectFromLoginPage(user.UserGuid.ToString(), false);
}
break;
case UserAuthenticationStatus.AuthButLocked:
//email/pwd match but account is locked so do something
ShowLockedAccountMessage();
break;
case UserAuthenticationStatus.EmailFoundIncorrectPassword:
case UserAuthenticationStatus.EmailNotFound:
case UserAuthenticationStatus.Unknown:
//either the email wasn't found, or the password was incorrect or there was some other problem
//present message stating this and offer chance to register
ShowFailedLoginMessage();
break;
default:
ShowUnavailableMessage();
break;
}
}
Wie Sie sehen können, es gibt nichts besonders kompliziert geht, aber trotz der Tatsache, dass die authCookie, die erstellt werden, in GenerateAuthenticationCookie(..) wird korrekt erstellt (soweit ich das sagen kann) es wird nicht bleiben.
Eine Sache, die ich bemerkt habe ist, dass wenn ich etwas code in die Application_AuthenticateRequest-Methode in der global.asax.cs, wie:
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(FormsAuthentication.FormsCookieName);
if (cookie != null)
{
int x = 4; //just a dummy line so that I can set a breakpoint
}
}
..., der Haltepunkt ist manchmal Treffer nach einer neuen browser-Sitzung, obwohl es beendet wird getroffen, sobald ich navigieren Weg von der Start-Seite (in diesem Fall ein dummy starten.aspx-Seite verwendet rein für Entwicklung & - Prüfung).
So, Entschuldigung für die lange Frage, aber ich bin wirklich Leid hier.
Dinge habe ich überprüft/ausprobiert
Sicherzustellen, dass der code ausgeführt wird - JA
Browser - Einstellungen- d.h. kein löschen von cookies beim beenden - KEINE LÖSCHUNG BESTÄTIGT
Sie versuchen, verschiedene timeouts - z.B. gleiche oder unterschiedliche auf das web.config timeout, scheint keine Rolle zu spielen...
...und natürlich mindestens zwanzig oder dreißig verschiedenen vorherigen Fragen, aber ohne Erfolg.
System/Dev Umgebung
Windows 7 64-bit, VS2010 (aber proj ist eine 3.5"), SQL Server 2008 Express.
Auf meinem dev-server, das problem bleibt so bin ich nicht sicher, ob es unbedingt die Umwelt -, die Maschine ist ein WS2008R2 box mit SQL 2008R2 - und das gleiche problem bleibt.
Hat jemand, irgendwo, irgendwelche Ideen für Dinge, die ich versuchen kann, hier? Ich habe das Gefühl, ich könnte diese Arbeit durch abfangen der ersten Application_AuthenticateRequest Treffer in global.asax.die cs und die Füllung etwas in den session state zu markieren als 'authentifiziert' (um zu vermeiden, eine teure Authentifizierung versuchen, jedes mal, wenn diese Methode aufgerufen wird, stellt sich heraus, dass Sie mehrmals pro Seite.
Vielen Dank im Voraus,
John
InformationsquelleAutor jtc | 2011-01-18
Du musst angemeldet sein, um einen Kommentar abzugeben.
OK, nachdem ich die ganze Zeit schreiben, dass, ich hatte einen moment der Klarheit und festgestellt, dass a) ich nicht tun müssen jeder, dass die Prüfung auf der Page_Load () (wenn das richtig funktioniert) die Anmeldung.aspx-Seite würde nicht aufgerufen werden, und (b) ich hätte in der Lage zu bekommen, um das cookie von der Session_Start - das ist, wo ich zog die TryAutoLogin code.
Schon das war ein Schritt nach vorn, aber trotz abrufen der Cookies und somit die Benutzer-guid aus, fand ich, dass ich noch immer Stakte zurück zum login.aspx-Seite.
Es war an diesem Punkt erinnerte ich mich an die Tatsache, dass ich in einem übergeordneten master-Seite und zwei untergeordnete master-Seiten - eine, die ich für nicht-Authentifizierung-Seiten (z.B. homepage) und eine für jene Seiten, die eine Authentifizierung erfordern. Ich vage erinnerte ein problem mit session-timeouts hatte und platziert den folgenden code in der OnInit-override:
...die in sich selbst war nicht so schlimm (und vermeiden einen bösen Fehler auf timeouts), sondern auch auf den start.aspx-Seite, fand ich dieses Kleinod:
...in der Page_Load!
So, was passiert war, war, dass ich versehentlich löschen der session, in die ich gestellt hatte, meine neu wiederhergestellte Benutzer-Datensatz. Was bedeutete, dass die Genehmigung master-Seite OnInit überschreiben, dann war die Erkennung der Abwesenheit des Benutzer-Objekt-und - ta dah! - Unterzeichnung der Benutzer aus, die wiederum entfernt die Zulassung cookie...
So, ein bisschen Verdrahtung und einige Detektivarbeit später, und ich kann dieses eine Bett.
Vielen Dank für das Lesen (auch wenn ich es herauszufinden, auf meine eigene)... 🙂
InformationsquelleAutor jtc