Asp.net Sessions Getting Crossed / Mixed Up

后端 未结 7 684
北恋
北恋 2020-12-04 20:19

Few weeks ago we had one of our customers contacting us saying that sometimes when he creates an activity it gets created under someone else\'s name!

We did some t

相关标签:
7条回答
  • 2020-12-04 20:49

    if removing the <%@ OutputCache NoStore="true" Duration="1" VaryByParam="*" at all (in all ascx files being in the line from Master to aspx too !!!) prevented from cross-sessions. having only one ascx with outputcache directive loaded, cross-sessions occured.

    It did not matter in my case if using sessionstat InProc ore StateServer, if having cookieless or cookie sessions.

    0 讨论(0)
  • 2020-12-04 20:49

    If you checked that output caching is not the problem

    There is already on answer from me here, but as it turned out my other solution (disabling the output cache) did not really solve our problem for us.

    Since in the question it is stated that caching is turned off, the only other possible (AFAIK) bug that can produce this is what turned out to be the real culprit in our case: we use a private variable in a ActionFilterAttribute.

    And because these are cached, storing private/personal data from a user in this way can also lead to session mix-up!

    This answer describes what our problem was and how to fix it:

    https://stackoverflow.com/a/8937793/1864395

    Also, I think it's good to mention that we were able to reproduce the problem by running Apache JMeter with a scenario for several users at the same time. It's a really nice tool (although not really user friendly/intuitive) used for (among other things) stress-testing. It's probably the only way to diagnose session mix-ups!

    0 讨论(0)
  • 2020-12-04 20:52

    We have just had a very similar problem, which occured at random, seemingly un-reproducibly.

    The problem turned out to be ASP.NETs Page caching mechanism - in our case the <%@ OutputCache tag in particular.

    There was a line we had used <%@ OutputCache NoStore="true" Duration="1" %> that basically meant if two users accessed the same page within 1 second of each other they would see the same page (including the logged in username of the other user). So if they refreshed said page, they got the correct information.

    In our case, changing said line to <%@ OutputCache NoStore="true" Duration="1" VaryByParam="*" %>, disabling kernel caching in IIS as in this link (http://lionsden.co.il/codeden/?p=446)

    and adding the following lines to the Page_Load event of the page in question:

    Response.CacheControl = "private";
    Response.ExpiresAbsolute = DateTime.Now.AddDays(-1d);
    Response.Cache.SetCacheability(HttpCacheability.NoCache);
    

    Seems to have solved the problem for us. Hopefully this helps someone else with a similar issue.

    0 讨论(0)
  • 2020-12-04 20:52

    Since this seems to fall into the extremely arcane problem territory, maybe it's time for a leap.

    You could stop using the ASP.NET session to store your identifiers altogether.

    You have a bunch of options of where you could stick this information instead. You could choose to encrypt it into the Forms Authentication ticket's UserData property (I've done this before in production, it works great for storing a key(s), csv of roles, or even small json objects). Past the forms auth ticket, you could write the information directly as your own cookie. You could also bypass cookies altogether.

    If you choose to bypass the cookies, you're basically entering into similar territory of the cookieless ASP.NET sessions. You have a couple of options, you could make the user identifier be apart of every single url as a query parameter. Another option would be to create a HttpModule that would add a hidden form input into every page response that contains the logged in user's identifier.

    If you go down the cookieless path absolutely make sure it's not possible to use your site as HTTP and every single request is HTTPS. Even more especially if you use the query parameter method.

    0 讨论(0)
  • 2020-12-04 20:54

    We had the same problem at the company I work at. We also realized that it was caused by output caching, which resulted in sending someone else's SessionId to the wrong person.

    We have now added the following <caching> element to our web.config.

    <configuration>
      [...]
      <system.webServer>
        [...]
        <caching enabled="false" enableKernelCache="false">
        </caching>
      </system.webServer>
      [..]
    </configuration>
    

    We can't guarantee this will solve it, because the problem is almost impossible to reproduce, but based on our research, this should solve it.

    Strangely, the link to a Microsoft article describing this problem that can be found on the internet gives some general page as if the page has been deleted.

    But there is this Microsoft article that seems to describe the same issue voor IIS 6:

    An ASP.NET page is stored in the HTTP.sys kernel cache in IIS 6.0 when the ASP.NET page generates an HTTP header that contains a Set-Cookie response

    Which describes the symptom as:

    Consider the following scenario. A Microsoft ASP.NET page contains the <%@ OutputCache %> directive. Additionally, the ASP.NET page generates an HTTP header that contains a Set-Cookie response. In this scenario, the ASP.NET page is stored in the HTTP protocol stack (HTTP.sys) kernel cache in Microsoft Internet Information Services (IIS) 6.0. Therefore, multiple users who access the same page may receive identical cookies.

    Update

    I found this really good article at Microsoft Premier Developer blog that explains a lot:

    ASP.Net Session Swapping – Why it happens and what can be done about it?

    0 讨论(0)
  • 2020-12-04 21:01

    Because you all disabled kernel-mode caching, I like to point out some other thinks.

    1) To correctly use the HttpContext.Current.User.Identity.Name, you first need to verify that your user is logedin by using the User.Identity.IsAuthenticated

    2) in this point Session.Add("CurrentUser", currentUser); what are you actual try to save ?

    Now I think that is the problem is on cache. The pages are stored somewhere in between your users and the one mix up with the other. Some of the headers that you can use to your page to avoid the cache on the middle proxy computers.

    Response.Cache.SetExpires(DateTime.UtcNow.AddYears(-2));
    Response.Cache.SetNoStore();
    Response.Cache.SetValidUntilExpires(false);
    Response.Cache.SetCacheability(HttpCacheability.NoCache);                
    Response.ExpiresAbsolute = DateTime.Now.Subtract(new TimeSpan(1, 0, 0, 0));
    Response.Expires = 0;
    Response.CacheControl = "no-cache";
    Response.AppendHeader("Pragma", "no-cache");
    

    Also I say that if your pages have data that you do not wish to share among your user you need to use Secure HTTPS pages, and set your cookies to be available only on secure pages by adding <httpCookies httpOnlyCookies="true" requireSSL="true" /> on web.config

    Also, check if you save your session on SQL server that you scheduled run the clean up routing every 1 minute.

    To been able to find some more information I suggest to store some hidden text on the pages, eg the date-time of the rendered, maybe a the last 4 digit of the userID, and what else you may thing that can help you see if the page come from a cache or not.

    0 讨论(0)
提交回复
热议问题