ASP.NET: Session.SessionID change entre les demandes

142

Pourquoi la propriété SessionID sur l'objet Session dans une page ASP.NET change-t-elle entre les demandes?

J'ai une page comme celle-ci:

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

Et la sortie ne cesse de changer à chaque fois que je frappe F5, indépendamment du navigateur.

Seb Nilsson
la source

Réponses:

225

C'est la raison

Lors de l'utilisation de l'état de session basé sur les cookies, ASP.NET n'alloue pas de stockage pour les données de session tant que l'objet Session n'est pas utilisé. En conséquence, un nouvel ID de session est généré pour chaque demande de page jusqu'à ce que l'objet de session soit accédé. Si votre application nécessite un ID de session statique pour toute la session, vous pouvez soit implémenter la méthode Session_Start dans le fichier Global.asax de l'application et stocker des données dans l'objet Session pour corriger l'ID de session, soit utiliser du code dans une autre partie de votre application pour stocker explicitement les données dans l'objet Session.

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

Donc, fondamentalement, à moins que vous n'accédiez à votre objet de session sur le backend, un nouvel identifiant de session sera généré à chaque requête

ÉDITER

Ce code doit être ajouté sur le fichier Global.asax. Il ajoute une entrée à l'objet Session afin que vous corrigiez la session jusqu'à ce qu'elle expire.

protected void Session_Start(Object sender, EventArgs e) 
{
    Session["init"] = 0;
}
Claudio Redi
la source
23
Je ne savais pas ça, je n'ai jamais eu de problème avec ça mais c'est intéressant à savoir
Pharabus
1
@Cladudio pourriez-vous simplement ajouter une ligne de code et votre réponse est parfaite. Des informations intéressantes issues d'une question intéressante ... plus une? ;)
Seb Nilsson
2
Fait intéressant, cela résout mon problème - mais le problème ne s'est manifesté qu'après environ 6 mois d'utilisation de la base de code sans problème. Je ne vois aucune raison pour laquelle cela aurait soudainement changé - quelqu'un peut-il suggérer une raison pour laquelle l'identifiant de session serait soudainement réinitialisé alors qu'il ne l'avait pas fait auparavant?
Moo
2
@KumarHarsh: une fois que vous stockez un objet sur la session, l'identifiant de session sera corrigé. C'est ce que je voulais dire avec "à moins que vous n'accédiez à votre objet de session sur le backend ...". Une fois que vous avez attribué someidla session, elle restera la même. Tenez compte du fait que cette réponse date de plus de 4 ans, je ne sais pas s'il y a eu une modification par rapport à cela.
Claudio Redi
9
J'ai remarqué que le simple fait d'ajouter la méthode Session_Start WITH RIEN EN IT à mon Global.asax a fait ce travail. Merci @Claudio pour le conseil.
Pedro
92

Il existe une autre raison, plus insidieuse, pour laquelle cela peut se produire même lorsque l'objet Session a été initialisé comme démontré par Cladudio.

Dans le Web.config, s'il y a une <httpCookies>entrée qui est définie sur requireSSL="true"mais que vous n'utilisez pas réellement HTTPS: pour une demande spécifique, le cookie de session n'est pas envoyé (ou peut-être pas retourné, je ne sais pas lequel) ce qui signifie que vous vous retrouvez avec une toute nouvelle session pour chaque demande.

J'ai trouvé celui-ci à la dure, passant plusieurs heures à faire des allers-retours entre plusieurs commits dans mon contrôle de source, jusqu'à ce que je trouve quel changement spécifique avait cassé mon application.

Neville Cook
la source
5
Je le savais mais je l'oublie encore tous les 3 mois environ et passe quelques heures à déboguer ..
Sotn
Dans mon cas, je testais sur localhost et le "requireSSL" dans web.config était défini sur "true". Merci.
William Pereira
c'était mon cas, et j'ai passé beaucoup trop de temps à essayer de le comprendre (j'avais un hareng rouge avec différents fichiers web.config).
jmoreno
Votre suggestion ci-dessus aide encore en 2018. C'est le scénario le plus fréquent. Merci!
Vijay Bansal
5

Dans mon cas, j'ai compris que le cookie de session avait un domaine qui incluait un www.préfixe, alors que je demandais une page sans www..
L'ajout www.à l'URL a immédiatement résolu le problème. Plus tard, j'ai changé le domaine du cookie pour qu'il soit défini sur au .mysite.comlieu de www.mysite.com.

Kniganapolke
la source
5

mon problème était que nous avions cet ensemble dans web.config

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

cela signifie que lors du débogage en non-SSL (par défaut), le cookie d'authentification ne serait pas renvoyé au serveur. cela signifierait que le serveur enverrait un nouveau cookie d'authentification (avec une nouvelle session) pour chaque demande de retour au client.

le correctif consiste soit à définir requireessl sur false dans web.config et true dans web.release.config, soit à activer SSL lors du débogage:

activer SSL

Josh
la source
En quoi est-ce différent de la réponse de Neville Cook de 2011?
Ian Kemp
4

En utilisant la réponse de Neville (suppression de requireSSL = true, dans web.config) et en modifiant légèrement le code de Joel Etherton, voici le code qui devrait gérer un site qui fonctionne à la fois en mode SSL et en mode non SSL, en fonction de l'utilisateur et de la page (je Je reviens dans le code et je ne l'ai pas encore testé sur SSL, mais je m'attends à ce que cela fonctionne - je serai trop occupé plus tard pour y revenir, alors le voici:

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
la source
2

Une autre possibilité qui fait changer le SessionID entre les demandes, même lorsque Session_OnStart est défini et / ou qu'une Session a été initialisée, est que le nom d'hôte de l'URL contient un caractère non valide (tel qu'un trait de soulignement). Je crois que c'est spécifique à IE (non vérifié), mais si votre URL est, par exemple, http://server_name/appIE bloquera tous les cookies et vos informations de session ne seront pas accessibles entre les demandes.

En fait, chaque requête lancera une session distincte sur le serveur, donc si votre page contient plusieurs images, balises de script, etc., chacune de ces requêtes GET entraînera une session différente sur le serveur.

Plus d'informations: http://support.microsoft.com/kb/316112

R. Aaron Zupancic
la source
2

Dans mon cas, cela se produisait souvent dans mes environnements de développement et de test. Après avoir essayé toutes les solutions ci-dessus sans succès, j'ai constaté que j'étais en mesure de résoudre ce problème en supprimant tous les cookies de session. L'extension de développeur Web rend cela très facile à faire. J'utilise principalement Firefox pour les tests et le développement, mais cela s'est également produit lors des tests dans Chrome. Le correctif fonctionnait également dans Chrome.

Je n'ai pas encore eu à faire cela dans l'environnement de production et je n'ai reçu aucun rapport indiquant que des personnes ne pouvaient pas se connecter. Cela semble également ne se produire qu'après avoir sécurisé les cookies de session. Cela ne s'est jamais produit dans le passé lorsqu'ils n'étaient pas en sécurité.

Matt L
la source
Mise à jour: cela n'a commencé à se produire qu'après avoir modifié le cookie de session pour le rendre sécurisé. J'ai déterminé que le problème exact était dû au fait qu'il y avait deux cookies de session ou plus dans le navigateur avec le même chemin et le même domaine. Celui qui a toujours posé problème était celui qui avait une valeur vide ou nulle. Après avoir supprimé ce cookie particulier, le problème a été résolu. J'ai également ajouté du code dans la méthode Global.asax.cs Sessin_Start pour vérifier ce cookie vide et, le cas échéant, définir sa date d'expiration sur quelque chose dans le passé.
Matt L
2

dans mon cas, c'était parce que je modifiais la session après avoir redirigé depuis une passerelle dans une application externe , donc parce que j'utilisais IP à la place sur localhost dans cette URL de page, il était en fait considéré comme un site Web différent avec des sessions différentes.

En résumé

faites plus attention si vous déboguez une application hébergée sur IIS au lieu d'IIS express et mélangez votre machine http: // Ip et http: // localhost dans différentes pages

Iman
la source
1

Mon problème était avec une application IPTV Microsoft MediaRoom. Il s'avère que les applications MPF MRML ne prennent pas en charge les cookies; changer pour utiliser des sessions sans cookies dans le web.config a résolu mon problème

<sessionState cookieless="true"  />

Voici un VRAIMENT vieux article à ce sujet: ASP.NET sans cuisine

denvercoder9
la source
1

Je suis sur .NET Core 2.1 et je suis bien conscient que la question ne concerne pas Core. Pourtant, Internet fait défaut et Google m'a amené ici dans l'espoir de faire gagner quelques heures à quelqu'un.


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 };
        }
    }
}

Notez que l'écriture et la lecture de session fonctionnent, mais aucun cookie ne semble être transmis au navigateur. Au moins, je n'ai pas trouvé d'en-tête "Set-Cookie" nulle part.

Krivar
la source
0

Assurez-vous que vous n'avez pas un délai d'expiration de session très court et assurez-vous également que si vous utilisez des sessions basées sur des cookies, vous acceptez la session.

La barre d'outils WebDeveloperToolbar de FireFox est utile dans de tels moments, car vous pouvez voir les cookies définis pour votre application.

Vendeurs Mitchel
la source
2
Je suppose que le délai d'expiration de ma session n'est pas inférieur à une seconde. Il change à chaque pression rapide sur F5.
Seb Nilsson
0

La réinitialisation de l'ID de session peut avoir plusieurs causes. Cependant, tout ce qui est mentionné ci-dessus ne concerne pas mon problème. Je vais donc le décrire pour référence future.

Dans mon cas, une nouvelle session créée à chaque demande a abouti à une boucle de redirection infinie. L'action de redirection a lieu dans l' événement OnActionExecuting .

J'ai également effacé tous les en-têtes http (également dans l' événement OnActionExecuting à l' aide de Response.ClearHeaders méthode ) afin d'empêcher la mise en cache des sites côté client. Mais cette méthode efface tous les en-têtes, y compris les informations sur la session de l'utilisateur, et par conséquent toutes les données du stockage temporaire (que j'utilisais plus tard dans le programme). Donc, même la configuration d'une nouvelle session dans l'événement Session_Start n'a pas aidé.

Pour résoudre mon problème, je me suis assuré de ne pas supprimer les en-têtes lorsqu'une redirection se produit.

J'espère que ça aide quelqu'un.

user3253726
la source
0

J'ai rencontré ce problème d'une manière différente. Les contrôleurs qui avaient cet attribut [SessionState(SessionStateBehavior.ReadOnly)]lisaient à partir d'une session différente même si j'avais défini une valeur dans la session d'origine au démarrage de l'application. J'ajoutais la valeur de session via le _layout.cshtml (peut-être pas la meilleure idée?)

C'était clairement le ReadOnly qui causait le problème parce que lorsque j'ai supprimé l'attribut, la session d'origine (et SessionId) restait intacte. L'utilisation de la solution de Claudio / Microsoft a résolu le problème.

goku_da_master
la source