ASP.NET: Session.SessionID ändert sich zwischen Anforderungen

142

Warum ändert sich die Eigenschaft SessionID für das Session- Objekt in einer ASP.NET-Seite zwischen Anforderungen?

Ich habe eine Seite wie diese:

...
<div>
    SessionID: <%= SessionID %>
</div>
...

Und die Ausgabe ändert sich jedes Mal, wenn ich F5 drücke, unabhängig vom Browser.

Seb Nilsson
quelle

Antworten:

225

Das ist der Grund

Bei Verwendung des Cookie-basierten Sitzungsstatus weist ASP.NET erst dann Speicher für Sitzungsdaten zu, wenn das Sitzungsobjekt verwendet wird. Infolgedessen wird für jede Seitenanforderung eine neue Sitzungs-ID generiert, bis auf das Sitzungsobjekt zugegriffen wird. Wenn Ihre Anwendung eine statische Sitzungs-ID für die gesamte Sitzung benötigt, können Sie entweder die Session_Start-Methode in der Global.asax-Datei der Anwendung implementieren und Daten im Session-Objekt speichern, um die Sitzungs-ID zu korrigieren, oder Sie können Code in einem anderen Teil Ihrer Sitzung verwenden Anwendung zum expliziten Speichern von Daten im Sitzungsobjekt.

http://msdn.microsoft.com/en-us/library/system.web.sessionstate.httpsessionstate.sessionid.aspx

Wenn Sie also nicht im Backend auf Ihr Sitzungsobjekt zugreifen, wird bei jeder Anforderung eine neue Sitzungs-ID generiert

BEARBEITEN

Dieser Code muss in die Datei Global.asax eingefügt werden. Es fügt dem Sitzungsobjekt einen Eintrag hinzu, sodass Sie die Sitzung bis zum Ablauf reparieren können.

protected void Session_Start(Object sender, EventArgs e) 
{
    Session["init"] = 0;
}
Claudio Redi
quelle
23
Ich wusste das nicht, hatte nie ein Problem damit, aber das ist interessant zu wissen
Pharabus
1
@Cladudio könnten Sie einfach eine Codezeile einwerfen und Ihre Antwort ist perfekt. Interessante Informationen aus einer interessanten Frage ... plus eine? ;)
Seb Nilsson
2
Interessanterweise behebt dies mein Problem - aber das Problem trat erst nach ungefähr 6 Monaten der problemlosen Verwendung der Codebasis auf. Ich kann mir keinen Grund vorstellen, warum sich dies plötzlich geändert hätte - kann jemand einen Grund vorschlagen, warum die Sitzungs-ID plötzlich zurückgesetzt wird, wenn sie es vorher nicht getan hat?
Moo
2
@KumarHarsh: Sobald Sie ein Objekt in einer Sitzung gespeichert haben, wird die Sitzungs-ID korrigiert. Das wollte ich mit "es sei denn, Sie greifen auf Ihr Sitzungsobjekt im Backend zu ..." sagen. Sobald Sie someiddie Sitzung zugewiesen haben, bleibt if gleich. Berücksichtigen Sie, dass diese Antwort älter als 4 Jahre ist und nicht sicher ist, ob diesbezüglich Änderungen vorgenommen wurden.
Claudio Redi
9
Ich habe festgestellt, dass das einfache Hinzufügen der Session_Start-Methode WITH NOTHING IN IT zu meiner Global.asax diese Funktion ermöglicht hat. Danke @Claudio für den Tipp.
Pedro
92

Es gibt einen anderen, heimtückischeren Grund, warum dies auch dann auftreten kann, wenn das Sitzungsobjekt initialisiert wurde, wie von Cladudio gezeigt.

Wenn in der Web.config ein <httpCookies>Eintrag festgelegt ist, für den requireSSL="true"Sie jedoch kein HTTPS verwenden: Für eine bestimmte Anforderung wird das Sitzungscookie nicht gesendet (oder möglicherweise nicht zurückgegeben, ich bin mir nicht sicher, welcher) dass Sie für jede Anfrage eine brandneue Sitzung erhalten.

Ich fand dies schwierig, verbrachte mehrere Stunden damit, zwischen mehreren Commits in meiner Quellcodeverwaltung hin und her zu gehen, bis ich herausfand, welche spezifische Änderung meine Anwendung beschädigt hatte.

Neville Cook
quelle
5
Ich wusste , das aber immer noch vergessen es alle 3 Monate oder so und ein paar Stunden verbringen Debuggen ..
SOTN
In meinem Fall habe ich auf localhost getestet und die "requireSSL" in web.config wurde auf "true" gesetzt. Vielen Dank.
William Pereira
Dies war mein Fall, und ich verbrachte viel zu viel Zeit damit, es herauszufinden (hatte einen roten Hering mit verschiedenen web.config-Dateien).
jmoreno
Ihr obiger Vorschlag hilft auch 2018 noch. Dies ist das häufigste Szenario. Vielen Dank!
Vijay Bansal
5

In meinem Fall stellte ich fest, dass das Sitzungscookie eine Domain mit www.Präfix hatte, während ich eine Seite mit der Nummer anforderte www..
Das Hinzufügen www.zur URL hat das Problem sofort behoben. Später habe ich die Domain des Cookies geändert, um sie auf .mysite.comanstatt zu setzen www.mysite.com.

Kniganapolke
quelle
5

Mein Problem war, dass wir dies in web.config eingestellt hatten

<httpCookies httpOnlyCookies="true" requireSSL="true" />

Dies bedeutet, dass beim Debuggen in Nicht-SSL (Standardeinstellung) das Authentifizierungscookie nicht an den Server zurückgesendet wird. Dies würde bedeuten, dass der Server für jede Anforderung ein neues Authentifizierungscookie (mit einer neuen Sitzung) an den Client zurücksendet.

Das Update besteht darin, entweder requireessl in web.config auf false und in web.release.config auf true zu setzen oder SSL beim Debuggen zu aktivieren:

Schalten Sie SSL ein

Josh
quelle
Wie unterscheidet sich das von Neville Cooks Antwort aus dem Jahr 2011?
Ian Kemp
4

Unter Verwendung der Antwort von Neville (Löschen von requireSSL = true in web.config) und geringfügiger Änderung des Codes von Joel Etherton ist hier der Code, der eine Site verarbeiten soll, die je nach Benutzer und Seite sowohl im SSL-Modus als auch im Nicht-SSL-Modus ausgeführt wird (I. Ich springe zurück in den Code und habe ihn noch nicht auf SSL getestet, erwarte aber, dass er funktionieren sollte. Ich werde später zu beschäftigt sein, um darauf zurückzukommen. Hier ist er also:

if (HttpContext.Current.Response.Cookies.Count > 0)
        {
            foreach (string s in HttpContext.Current.Response.Cookies.AllKeys)
            {
                if (s == FormsAuthentication.FormsCookieName || s.ToLower() == "asp.net_sessionid")
                {
                    HttpContext.Current.Response.Cookies[s].Secure = HttpContext.Current.Request.IsSecureConnection;
                }
            }
        }
Reid
quelle
2

Eine andere Möglichkeit, die dazu führt, dass sich die Sitzungs-ID zwischen Anforderungen ändert, selbst wenn Session_OnStart definiert und / oder eine Sitzung initialisiert wurde, besteht darin, dass der URL-Hostname ein ungültiges Zeichen enthält (z. B. einen Unterstrich). Ich glaube, dies ist IE-spezifisch (nicht verifiziert), aber wenn Ihre URL beispielsweise lautet, http://server_name/appblockiert IE alle Cookies und Ihre Sitzungsinformationen sind zwischen Anfragen nicht zugänglich.

Tatsächlich wird für jede Anforderung eine separate Sitzung auf dem Server gestartet. Wenn Ihre Seite also mehrere Bilder, Skript-Tags usw. enthält, führt jede dieser GET-Anforderungen zu einer anderen Sitzung auf dem Server.

Weitere Informationen: http://support.microsoft.com/kb/316112

R. Aaron Zupancic
quelle
2

In meinem Fall passierte dies häufig in meinen Entwicklungs- und Testumgebungen. Nachdem ich alle oben genannten Lösungen ohne Erfolg ausprobiert hatte, stellte ich fest, dass ich dieses Problem beheben konnte, indem ich alle Sitzungscookies löschte. Die Webentwickler-Erweiterung macht dies sehr einfach. Ich benutze Firefox hauptsächlich zum Testen und Entwickeln, aber dies geschah auch beim Testen in Chrome. Das Update funktionierte auch in Chrome.

Ich musste dies noch nicht in der Produktionsumgebung tun und habe keine Berichte von Personen erhalten, die sich nicht anmelden konnten. Dies schien auch erst zu geschehen, nachdem die Sitzungscookies sicher gemacht wurden. Es ist in der Vergangenheit nie passiert, wenn sie nicht sicher waren.

Matt L.
quelle
Update: Dies begann erst, nachdem wir das Sitzungscookie geändert hatten, um es sicher zu machen. Ich habe festgestellt, dass das genaue Problem durch zwei oder mehr Sitzungscookies im Browser mit demselben Pfad und derselben Domäne verursacht wurde. Das Problem war immer das, das einen leeren oder Nullwert hatte. Nach dem Löschen dieses bestimmten Cookies wurde das Problem behoben. Ich habe auch Code in die Sessin_Start-Methode von Global.asax.cs eingefügt, um nach diesem leeren Cookie zu suchen und in diesem Fall das Ablaufdatum auf etwas in der Vergangenheit festzulegen.
Matt L
2

In meinem Fall lag dies daran, dass ich die Sitzung nach dem Umleiten von einem Gateway in einer externen Anwendung geändert habe. Da ich also IP auf localhost in dieser Seiten-URL verwendet habe, wurde dies tatsächlich als unterschiedliche Website mit unterschiedlichen Sitzungen angesehen.

Zusammenfassend

Achten Sie mehr darauf, wenn Sie eine gehostete Anwendung auf IIS anstelle von IIS Express debuggen und Ihren Computer http: // Ip und http: // localhost auf verschiedenen Seiten mischen

Iman
quelle
1

Mein Problem war mit einer Microsoft MediaRoom IPTV-Anwendung. Es stellt sich heraus, dass MPF-MRML-Anwendungen keine Cookies unterstützen. Das Ändern der Verwendung von Cookieless-Sitzungen in der web.config hat mein Problem behoben

<sessionState cookieless="true"  />

Hier ist ein WIRKLICH alter Artikel darüber: Cookieless ASP.NET

denvercoder9
quelle
1

Ich bin auf .NET Core 2.1 und mir ist klar, dass es bei der Frage nicht um Core geht. Das Internet fehlt jedoch und Google hat mich hierher gebracht, in der Hoffnung, jemandem ein paar Stunden zu ersparen.


Startup.cs

services.AddCors(o => o.AddPolicy("AllowAll", builder =>
            {
                builder
                    .WithOrigins("http://localhost:3000")     // important
                    .AllowCredentials()                       // important
                    .AllowAnyMethod()
                    .AllowAnyHeader();       // obviously just for testing
            }));

client.js

const resp = await fetch("https://localhost:5001/api/user", {
            method: 'POST',
            credentials: 'include',                           // important
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(data)
        })

Controllers/LoginController.cs

namespace WebServer.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class UserController : ControllerBase
    {
        [HttpPost]
        public IEnumerable<string> Post([FromBody]LoginForm lf)
        {
            string prevUsername = HttpContext.Session.GetString("username");
            Console.WriteLine("Previous username: " + prevUsername);

            HttpContext.Session.SetString("username", lf.username);

            return new string[] { lf.username, lf.password };
        }
    }
}

Beachten Sie, dass das Schreiben und Lesen der Sitzung funktioniert, jedoch keine Cookies an den Browser übergeben werden. Zumindest konnte ich nirgendwo einen "Set-Cookie" -Header finden.

krivar
quelle
0

Stellen Sie sicher, dass Sie kein sehr kurzes Sitzungszeitlimit haben, und stellen Sie außerdem sicher, dass Sie die Sitzung akzeptieren, wenn Sie Cookie-basierte Sitzungen verwenden.

Die FireFox webDeveloperToolbar ist in Zeiten wie diesen hilfreich, da Sie die für Ihre Anwendung gesetzten Cookies sehen können.

Mitchel Sellers
quelle
2
Ich vermute, dass mein Sitzungszeitlimit nicht unter einer Sekunde liegt. Es ändert sich mit jedem schnellen F5-Druck.
Seb Nilsson
0

Das Zurücksetzen der Sitzungs-ID kann viele Ursachen haben. Die oben genannten beziehen sich jedoch nicht auf mein Problem. Also werde ich es als zukünftige Referenz beschreiben.

In meinem Fall führte eine neue Sitzung, die bei jeder Anforderung erstellt wurde, zu einer Endlosumleitungsschleife. Die Umleitungsaktion findet im Ereignis OnActionExecuting statt.

Außerdem habe ich alle http-Header gelöscht (auch im OnActionExecuting- Ereignis mithilfe der Response.ClearHeaders- Methode), um das Zwischenspeichern von Websites auf der Clientseite zu verhindern. Diese Methode löscht jedoch alle Header, einschließlich Informationen über die Sitzung des Benutzers, und folglich alle Daten im temporären Speicher (die ich später im Programm verwendet habe). Selbst das Festlegen einer neuen Sitzung im Session_Start-Ereignis hat nicht geholfen.

Um mein Problem zu beheben, habe ich sichergestellt, dass die Header bei einer Umleitung nicht entfernt werden.

Hoffe es hilft jemandem.

user3253726
quelle
0

Ich bin auf andere Weise auf dieses Problem gestoßen. Die Controller mit diesem Attribut [SessionState(SessionStateBehavior.ReadOnly)]lasen aus einer anderen Sitzung, obwohl ich beim Start der App in der ursprünglichen Sitzung einen Wert festgelegt hatte. Ich habe den Sitzungswert über die Datei _layout.cshtml hinzugefügt (vielleicht nicht die beste Idee?)

Es war eindeutig das ReadOnly, das das Problem verursachte, denn wenn ich das Attribut entfernte, blieb die ursprüngliche Sitzung (und SessionId) im Takt. Die Verwendung der Lösung von Claudio / Microsoft hat das Problem behoben.

goku_da_master
quelle