?
Solved

Session Expired when moving between HTTP and HTTPS in ASP.NET

Posted on 2010-01-12
27
Medium Priority
?
4,490 Views
Last Modified: 2012-05-08
We have an ecommerce site using ASP.NET where all the product pages are in HTTP and the payment page is in HTTPS (with SSL).  The SSL is across the site so users can also view all the pages over HTTPS also.

We have a session expiry page on the server and whenever the session expires the user is redirected to the session expired page.  On this page we have an Email component which emails us back all the server variables for us to diagnose why session expiry is occuring.  

It looks like when people are selecting a product and going to payment page we are facing this session expiry.  This does not happen all the time only in some instances.   I have done some research and found some links but most say that its not possible at all to share session between HTTP and HTTPS.  If thats the case then every session would have expired when the payment page was called which is not what is happening, unless the user started with HTTPS and continued to payment with HTTPS.

We use cookies for Session Management.

I was hoping that this issue would be common for many applications where the payment only is over secure channels and maybe one the experts here has an answer to this.  Maybe there is a better way to handle this and any help would be appreciated.
0
Comment
Question by:globalonline
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 14
  • 10
27 Comments
 
LVL 39

Expert Comment

by:abel
ID: 26304592
Your resources are correct, it is not possible to share sessions between HTTP and HTTPS. That would mean a huge security breach (unsecure cookies on a secure page). Likewise, it is not possible to take sessions from one domain (www.example.com) to another domain (secure.example.com).

That the session is not always shown as "expired" can have a different reason. If it is coded in such a way that a "new" session is considered new and that on the entry page of your payment system, the session is newly created based on the input data from the referring page, then that might explain why is works most of the time.

Most browsers don't store cookies of secure pages at all, other then in memory. That means, if a user closes a window and opens it again, or leaves an HTTPS page and comes back, it is possible that the session expires or is removed. If the page is something else then the entry page, and the code checks for a filled session, then this can explain the session expired on the other pages.

By default, sessions are alive for 20 minutes. When someone stays for 20 minutes on HTTPS and then moves back, the session on the HTTP page will be expired, because each has its own expiry date. And vice versa (assuming the browser keeps the session in memory).

These three things together, but esp. the last issue, can give surprising results. The only solution is to use a way to share the session or to move the session id from the non-secure page to the secure page. But that'll require DB sessions, I think (but haven't thought it through, other solution may be possible).
0
 

Author Comment

by:globalonline
ID: 26305211
Hi Abel, Thank you  for your response.

I do not want the whole site on HTTPS;
Alternatively if I were to maintain sessions in the state server or SQL Database and was willing to live with the performance overheads then I can have payment on a seperate subdomain eg  booking.xyz.com or secure.xyz.com

I think from your post what we can do perhaps is generate a new session id on a HTTPS page instead of on the HTTP (default.aspx page).  So if someone requests any page over HTTP on the site we would first create a HTTPS session and then they can continue on HTTP and on to payment page over HTTPS.

The idea is that throughout the site the HTTPS session is the one the site is working on, Will that work?  what are your thoughts on this ?
0
 
LVL 39

Accepted Solution

by:
abel earned 1000 total points
ID: 26305762
One problem with your approach: a session is automatically created and you cannot change that process (not entirely true: you can, but that requires writing a SessionProvider and a SessionIDProvider, if I got the names correct, and that's a rather involved process).

The overhead to your database would be minimal, if you already use a database, but I can't fully judge that, not knowing what's in the session and what the load is on the session. Also, using a DAL / DAO with first or second level caching to the DB will make this either a no-brainer or a real performance killer.

The normal and simplest trick one can perform is actually removing the Secure setting of the cookie (sorry, I didn't think of this at first). How to do so is excellently and easily explained in this stackoverflow answer.

If your HTTPS and HTTP sites have different DNS names, this won't hold and it may be that the only "simple" way out is proxying the cookie somehow or using a state server. But apparently, it is possible to use a dirty hack like this one for a quick fix.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:globalonline
ID: 26306382
I am going to try with the approach you have suggested of removing the secure setting of the cookie.

We are using a SQL Database and right now payment page is on the same domain but on HTTPS.  If the above doesnt work then I guess I will have to try and use the DB and store sessions in SQL Server, but it does have overheads as it has to serialise and deserialise the session data.  

how do we check what is the load on the session ?

Thanks for your valuable inputs again.
0
 
LVL 39

Expert Comment

by:abel
ID: 26306614
> I am going to try with the approach you have suggested
Note that it only works if the domains are the same. I.e., http://example.com and https://example.com.

> how do we check what is the load on the session ?
That's very hard to answer. You can know if you know the code, but even then, it can be non-trivial. A session is "heavy" if it contains heavy objects like images, because if they need to be stored in the database, that might generate too much traffic.

The actual load depends also on the amount of simultaneous users. You can check this using the Performance Monitor counters for "Active Sessions". But be aware of this bug (which appeared on all servers I've seen so far) so take the number a bit cautious: if it's unreasonably high then don't believe the number.
0
 

Author Comment

by:globalonline
ID: 26331965
Hi abel,  we have tried everything but the session expiry issue persists.

1) Firstly we added the secure settting of the cookie to false so that it is available in both SSL and non SSL modes.

2) We also added the machineKey in the config so that the Cryptography Errors on .AXD files are removed

3) We added no allow on the robots.txt file for any .AXD resource as that can also cause event log errors and to avoid any recycle of the worker process

4) We changed the application pool for the website so that it has its own dedicated application pool and change the settings for recycle to 35,000 requests from minutes.

5) We saw that some browsers it expires more than in others (more in safar i and mac OS X) and iPhone

Still getting around 15-20 session expiry from around 300 unique visits.

Any ideas how we can debug this further?  We have an auto generated email now every time session expires which dumps all the HTTP server variables and all session variables
0
 
LVL 39

Expert Comment

by:abel
ID: 26332007
To continue, I need to know a few things:

1) Can you confirm that http://example.com and https://example.com both work (i.e., that their domain names are exactly equal).

2) Can you turn on Performance Monitor and add counters for Abandoned Sessions, Active Sessions and Expired Sessions and Sessions Total? Also add counters for exceptions and application pool recycles.

3) Add code in the Application_Start event to log the start events explicitly (just use some simple text file).  I do this always as a general measure: when there's a recycle or a fierce .NET internal error, the Application may be restarted. Always open and close this file so that it is flushed immediately.

4) Make absolutely certain that Session Expiry is not the actual issue. Defaults to 20 minutes, but can be set to any other value. Set it to 60 or even 120 minutes and see what the difference is.

5) There's been a bug with .NET that changing the .NET expiry mid-session reset the session occasionally. If you set the expiry time in code, this may well be the cause of your issue. There's a fix for this.

There're more questions I'd like to ask, but let's start out with these and see what that gives us.
0
 

Author Comment

by:globalonline
ID: 26346182
1) Can you confirm that http://example.com and https://example.com both work (i.e., that their domain names are exactly equal).

yes they both work, but when we type  https://www.example.com  it then redirects itself to http://www.example.com so the URL is being changed from code.

2)  Are you asking me to use System Monitor (PerfMon) OR the ASP.NET Applications performance object ?

3) Do you have an example of this code please?

4) Session Expiry has been set to 1 full day, so i have a feeling that the issue is due to some other code problem.

5) Please advise what he fix would be so that I can check that also.

Many thanks for your help. do you think that if i sent you the site flow you can analyse this better?  The site does use a Web Service also to get data which is on HTTPS.
 
0
 
LVL 39

Expert Comment

by:abel
ID: 26348132
ad 1) I actually meant to ask how you designed the paths, sorry for being unclear: http://example.com/normal and https://example.com/secure. I assume that not all your secure connections redirect back to normal connections. When you set a cookie on /secure and you go to /normal, it may (depending on settings) be unreadable. When you set a cookie on / (root) and you go to either /secure or /normal, it will be readable by both.

ad 2) I meant the asp.net  performance objects that you can use from within Performance Monitor (perfmon).

ad 3) see below. Add it to your Global.asax. You can use the session start/end to check whether a new session is created with a different ID when you switch from http to ssl.

ad 4) where do you set this, through code or through web.config or other? Is it really set correctly? You can test Session.Timeout through code, it should give 1440.

ad 5) The fix was this one, but it applies only to 1.1. (funny I still remembered it though). When you check your ASP.NET counter in perfmon, be aware of this other bug for strange active session counts. I've never seen a site with .NET 3.5 without that bug.
But:
I conjured up some scenarios I figured could hamper session lifetime. With it I googled a bit and found this excellent explanation that seems to be applicable. If you add the code below, this will show up in your logs (the app resets, I mean).



void Application_Start(object sender, EventArgs e) 
{
     CallYourLoggerHere.Info("Application is started");
}
    
void Application_End(object sender, EventArgs e) 
{
     CallYourLoggerHere.Info("Application has ended");
}
void Session_Start(object sender, EventArgs e) 
{
     CallYourLoggerHere.Info("Session with ID xxx has started");
}

void Session_End(object sender, EventArgs e) 
{
    // is only triggered for in-process sessions
    CallYourLoggerHere.Info("Session with ID xxx has ended");
}

Open in new window

0
 

Author Comment

by:globalonline
ID: 26348715
1- The cookie is set on root and in normal mode, we have traffic coming directly to inner pages (product pages) and not to default via search engines, they are all on HTTP; majority of traffic is coming to default.aspx in the root.

2- I will check this

3-Thanks will add this today and implement logging.
4-This is set via web.config   <sessionState timeout="2880" />  How do we test via code?


We have seen that mainly the session is expiring in the search results page when users select a product to goto payment page which is on HTTPS.

Many thanks for this I will implement the logging today.  

I noticed in the event log that there was an application error with invalid viewstate as well today. I have pasted that below


Exception information: 
    Exception type: HttpException 
    Exception message: Invalid viewstate. 
 
Request information: 
    Request URL: http://www.americacarrental.com/ScriptResource.axd?d=dJP22XF61d4n0Cyt1OqboKtX6QmAY9cqBvBxC33sCQI0pkDv5fI3nHpuKRTBfmIKnp2oKAz2tljnVN1KDS5CS0YG1lAYtyCWuUnZavMh2eet_value()http://www.americacarrental.com/ScriptResource.axd?d=dJP22XF61d4n0Cyt1OqboKtX6QmAY9cqBvBxC33sCQI0pkDv5fI3

Open in new window

0
 
LVL 39

Expert Comment

by:abel
ID: 26348946
Just curious:

a) suppose a user enters your site on example.com/site/search

b) the session ID will be set on that page, not sure what the path of the cookie will be though, you can check this with Web Developer Toolbar. Normally, ASP.NET will make sure that the path of such cookie is / (root).

c) suppose the path is /site/search. When the user then goes to example.com/site/payment, which is secure (or not, doesn't matter), the cookie will not be read anymore and a new one will be created.

To troubleshoot this, it is important to keep an eye on the ASP.NET_SessionId cookie. If you have found yourself a situation where you can always reproduce this behavior, go to that page with Firefox, click Cookies > View Cookies in your Web Dev. Toolbar and inspect the path and the value of ASP.NET_SessionId. Then go to the page where the session is supposed to be expired, and check the ASP.NET_SessionId again.

You can check the timeout in code by simply writing Session.Timeout to some log of some sort. Same with the Session.ID, which is important for finding out whether a new session is really been made, or whether the same session is used but with lost data. Add these to your Session_Start events.
0
 
LVL 39

Expert Comment

by:abel
ID: 26348956
> invalid viewstate

Invalid ViewState happens occasionally. Either because of a bug, because of transmission failure or because someone tries to hack in (just happens). It won't hamper with your cookie or session settings.
0
 
LVL 39

Expert Comment

by:abel
ID: 26348964
PS: if you have a reproducible sequence of actions, can I test them on your site to see if I can find anything?
0
 

Author Comment

by:globalonline
ID: 26356024
No we are not able to replicate this. I have emails which I get every time this happens

The site is http://www.americacarrental.com 

Flow is as below
1) Enter on home page www.americacarrental.com (Default.aspx) and then do a search by entering any location and some dates; the search criteria is stored in a Hash Table and that is then stored in a session.  This home page has a control called 'NewLookcrtlSearchVehicle.ascx' which is the booking engine you see on the home page.

2) Once you hit submit you are then taken to the search results page (SearchResult.aspx); here the page aslo calls SupplierSummaryGrid.aspx for the summary display and then SearchGrid.aspx which has the search results. On the top right you will see option to modify the search criteria and thats via another control called crtlSearchVehicle.ascx

3) Also we have traffic coming to inner pages; organic traffic from search engines (eg location pages and supplier pages etc each having a search control called :crtlSearchVehicle.ascx ) Location Landing page URL: http://www.americacarrental.com/car-hire-atlanta-airport.htm   and for Supplier it is http://www.americacarrental.com/car-hire-alamo.aspx?suppid=291 

4) Once you select a vehicle it then goes to the payment page :  paymentdetails.aspx (So its just a 3 step process) this page is on HTTPS

The vehicle results is a DataSet which is kept on session in the SearchResults page and many time it is when users click to select a vehicle the session expires. At this stage either the session expires when control goes to HTTPS-payment page or something else which causes the Session with vehicleResults Dataset to expire.

Hope I have explained the flow and the main components of the site.  It has only 4-5 aspx pages thats all.
0
 
LVL 39

Expert Comment

by:abel
ID: 26358029
Yes, I think that flow is excellently explained. I just had a look. I can't do a full booking and then return to do a real test, but from the looks of it, your cookies seem ok and they don't change when moving from normal to SSL.

Because it only happens occasionally, add sufficient logging to your "session expired" page. Also, check the routine that takes care of the redirection. Perhaps you're only checking for a certain value inside the session, which simply isn't always set if you take a different route through your site.

If you feel that InProc is the cause (i.e., because of server resets), you can consider using a session state server. This is not that hard to setup. And even when you update your website (which forces a reset), when you recycle the app pool or reset IIS, the sessions will not be removed.
0
 
LVL 39

Expert Comment

by:abel
ID: 26358037
PS: have you already tried checking the logfiles and mimicking the actual paths a user has clicked through your site when they mailed you about the error?
0
 

Author Comment

by:globalonline
ID: 26358651
Yes i am checking the log files via log analyser.  Some of them just land on default and sessions expires.  We had around 28 yesterday out of total 380 unique visits.  Is that normal ?

There are some expiry where useragent is Facebook etc these I think are genuine ones as it maybe bookmarks.  We have seen that many are from Apple OS X which we cant test at our end but I think that is also causing the expiry.

Many of the expires are from a single Ips (10 from single IP - happening almost every day)

You can do a full booking by using a dummy test name and a test card (VISA - 4111111111111111) that way you will see thank you page.
0
 
LVL 39

Expert Comment

by:abel
ID: 26358818
Before I do that: the 10 requests of the single IP that went wrong, are these different users? Or are they behind a proxy? To find out can be a bit tricky: compare the full browser identification string or check whether requests are just too unlikely to originate from the same system.

People from Apple usually use Safari, Firefox, Chrome (in that order). Safari is also available for Windows, you can try it out.
0
 

Author Comment

by:globalonline
ID: 26358943
Some of them do use proxy and I have seen various UserAgent   as below

1) Facebook share follower
2) Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-us) AppleWebKit/531.21.8 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10 X-Purpose: preview X-BlueCoat-Via: 0ED7065D8C619C5C

We have a few from the above, this looks like they use the BlueCoat Proxies and old pages are cached.

3) Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_1_2 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Mobile/7D11
4) facebookexternalhit/1.0 (+http://www.facebook.com/externalhit_uatext.php)
5) Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; GTB6.3; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729)

We have checked in safari and no issues.  
0
 
LVL 39

Expert Comment

by:abel
ID: 26566487
I think my answer to the last comment got lost somewhere. I believe my conclusion was something around the alternative PC market (not being PC's per se). I.e., you list an iPhone, a Media Center PC, some non-browsers (Facebook, perhaps other crawlers?). The webkit browser may also be from a mobile phone.

Anyway, my apologies it didn't came through earlier. @TheLearnedOne, I think it's fair to try to keep this open, if globalonline still needs this issue resolved.
0
 

Author Comment

by:globalonline
ID: 26576551
Unfortunately the issue still persists although fewer session timeouts are being noticed.  A few occur from the same set of IP address each day unique in that day.  

I think the session timeout value is also not working as i have tested and while the value is <sessionState timeout="2880" />   in web.config, the session still expires if the search result page is open for 30-40 minutes.

1- Is there any way to prevent session expiry from the code which would work say for 6 hours or 12 hours?

2- Is there anyway to prevent caching requests at all from code so that proxy servers like bluecoat etc do not cache the search result page at all?

3- We seem to have got the server errors related to .xsd AJAX ( Cryptography Errors on .AXD files are removed ) request back again, even though we do have the machine key added to the web.config which was given as a suggested solution to this issue. Any Ideas? Do we have to change and regenerate the machine key again every time we recompile?
 

 
Request URL: http://www.americacarrental.com/webresource.axd?d=9s32lhasi-8fcjmsfjovoq2&amp;t=633912912061251250 
    Request path: /webresource.axd

Open in new window

0
 
LVL 39

Expert Comment

by:abel
ID: 26576611
Glad the issue occurs less frequently now. Remember that session timeout will always occur and should occur, you can't do anything about it (the alternative would be to keep sessions forever, which would eventually eat all your available system memory and slow your application down)

1) You can use Session.Timeout, but this has effectively the same effect as sessionstate timeout in the web.config. Perhaps something overrides that value by code? Are you sure it is the session, or is it possibly a cookie that you rely on?

2) Yes, use "Response.Cache.SetNoStore();"

3) no, you should not need to regenerate. But cryptography errors are of an entirely different kind, not sure it's related to the session timeouts.
0
 

Author Closing Comment

by:globalonline
ID: 31676154
This solutions has helped us to solve some of the issues.
0
 

Expert Comment

by:jbonney
ID: 31206822
I have several sites that successfully traverse from http to https and back again without losing their session variables, however, I recently ended up on this discussion after my newest site lost the session variables.

One thing I noticed was that the newest site used Win Server 2008/IIS 7 whereas the previous sites used Win Server 2003/IIS 6. Anyway, it seems the default behavior is different on the newer server.

The solution is to change this setting in the IIS console...
1) From the home screen of the IIS console, open "ASP" in the "IIS" section
2) In the "Services" section, expand "Session Properties"
3) For the property "New ID onSecure Connection", select "False" (the default is "True")

That should do it.
0
 
LVL 39

Expert Comment

by:abel
ID: 31263178
@jbonney: thanks very much for this information! A pity we cannot alter (our own) solutions on this site, otherwise I would add this.
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
The article shows the basic steps of integrating an HTML theme template into an ASP.NET MVC project
In this video we outline the Physical Segments view of NetCrunch network monitor. By following this brief how-to video, you will be able to learn how NetCrunch visualizes your network, how granular is the information collected, as well as where to f…
NetCrunch network monitor is a highly extensive platform for network monitoring and alert generation. In this video you'll see a live demo of NetCrunch with most notable features explained in a walk-through manner. You'll also get to know the philos…
Suggested Courses

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question