4

Short Description: the IIS Server Variable "HTTP_COOKIE" is expiring in at a time that doesn't seem to be controlled by any timeout variable and I'd like to know what is causing it. I've tried modifying all of the timeout/expiry controlling values I can see within IIS and nothing is changing it from roughly 20-30 mins.

Detail:

We have an application with a C++ back-end which uses the IIS Server Variable "HTTP_COOKIE" to store state data, most importantly the session ID (GUID, for the rest of the question) of the current session for that user. There is a requirement that any user can only be logged in once, and the GUID is one of the pieces of data used to enforce this - every time the user logs on, the GUID is refreshed. Every time a user completes an action, the GUID stored locally in the tab sessionStorage (i.e., that value that it has when the user first logged in on that tab) is checked against the GUID that was most recently created for that user. If they don't match, the user is kicked off the application on that tab.

Now, the problem is that there are two situations where the GUID will be refreshed: when a user logs in, and when the application fails to find an existing GUID within its memory or the HTTP_COOKIE string. Case 1 is fine - that's what we want. Case 2 is annoying, because there appears to be something in the IIS setup that is causing the HTTP_COOKIE to be cleared after 20-30 minutes (I haven't pinned down exactly how long it is). We had a look, and we've found a lot of timeouts that could be causing this, but modifying each in turn to 1 minute, resetting IIS and trying again made no difference to the timeout:

  • Sites=>Default Web Site=>Session State=>Cookie Setting=>Time-out
  • Sites=>Default Web Site=>ASP=>Session Properties=>Time-out
  • Sites=>Default Web Site=>Allstate application=>ASP=>Session Properties=>Time-out

The only one that Did make a difference was:

  • Application Pool => Advanced Settings => Process Model => Idle Time-out

But this was because it was kicking in before the other timeout and resetting everything, rather than that it was what was causing the one we want to remove. Within our system this timeout is normally disabled (set to 0 minutes, as per MSDN guidelines).

I've trawled through everything I can think of - it's definitely an IIS issue as the server-side code is performing exactly the same task whether it expires or not, the only difference is that the HTTP_COOKIE string is gone after the above idle time, so it generates a new GUID as it can't find the existing one. There are no errors in the event log implying that something has run out of space or otherwise failed causing a reset.

What I'm asking is whether anyone knows of anything else which could be controlling this, and where this can be disabled/modified to a larger value. If you know what this is and know that it's impossible to bypass, that would also be useful to know. If this is the case, if anyone has a suggestion about a better way to store the GUID for the user session they would also be appreciated!

Thanks in advance.

P.S. I'm not looking for a better way to handle this if it involves a total rewrite of the system - the existing one is unnecessarily complicated, but the application is old (~15 years) and contains a lot of archaic methods that we're not being given the resource to sort out, so the only option I have is to work with the system as it is.

Ieuan Stanley
  • 1,248
  • 8
  • 20
  • Come on people! Surely **SOMEONE** knows something! – Ieuan Stanley Jan 07 '16 at 16:11
  • What does the code look like on the server where the cookie is generated? Sounds like the cookie simply expires on the client, at which point the client will stop sending it in subsequent requests... – user1429080 Jan 08 '16 at 09:45
  • The cookie may well be expiring on the client (that's almost certainly what's happening by some method, either the cookie itself or the session), the question is **why**. As far as I can tell we've covered every timeout or default expiry we could find, what I'm looking for is what exactly is causing it (the cookie or the session, whichever it is) to expire after 20-30 mins – Ieuan Stanley Jan 08 '16 at 10:02
  • Well if you are checking a cookie for a GUID value, then that GUID value must be put into a cookie at some point. What does the code look like in the application that generates the cookie? Does it include an expiry time for instance? – user1429080 Jan 08 '16 at 10:07
  • The code isn't going to help much in this case - the cookie string (including the GUID) is generated and then sent to the IIS Request using the `HSE_REQ_SEND_RESPONSE_HEADER_EX` support function. The data then remains there until it is mysteriously cleared by some timeout/expiry we can't place which is what I'm looking for answers on. There is no expiry time included on the cookie, which according to the IIS documentation means it should use the default, being the session expiry/end, which is SUPPOSED to be the closure of the tab. I'm just running a test now manually defining a cookie expiry – Ieuan Stanley Jan 08 '16 at 10:16
  • just a theory, but did you try checking the machine.config? I'm pretty sure that all web.config settings inherit from that. You should see it in the `C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config` file (assuming v4 x64 .net) – Terry Kernan Jan 12 '16 at 23:21

2 Answers2

1

HTTP_COOKIE is just the concatenated string passed via the request/response headers for all valid cookies for that domain stored on the client. You're basically being affected by the default timeout for the Session ID. Just create your own session identifier (e.g. generate a GUID stored in a database table) and have the client store it as a cookie with a different expiration date. Update the expiration date with every valid user interaction to extend the session. Problem solved.

Cahit
  • 2,484
  • 19
  • 23
  • what do you mean by "The default timeout of the session ID"? Is this a value that is set within IIS? Everything I've read thus far implied that the session lasts for the lifetime of the tab/browser, and that cookies should be default expire at the end of the session. Neither of these things would have to be true in order for what you're saying to work. – Ieuan Stanley Jan 08 '16 at 09:40
  • There's a fundamental misunderstanding. HTTP is a completely stateless protocol, so what creates the session is something persistent that can identify recent activity from the same browser, which is basically a unique session identifier generated on the server and stored on the client. The IIS server has no way of knowing when the user is still active other than "assuming" he's gone by comparing the last interaction time to the current time. If it's more than X minutes, then IIS calls the session "expired". (Cont'd below) – Cahit Jan 13 '16 at 20:40
  • Since you're using your own ISAPI extension, basically it's up to your application to manage the session timeout, by checking and updating the cookie used to track the session ID with each interaction. If you were using ASP, which is an ISAPI DLL itself, then the timeout would be the lifetime of the ASPSESSIONID cookie, by default set to 20 minutes. With cookies, if you don't set a specific lifetime, the browser will discard it when it's closed. However, this won't trigger an event on the server, so the server won't know when the tab/browser is shut down. (Cont'd below) – Cahit Jan 13 '16 at 20:53
  • Hence, the server will reissue a new cookie with a new session identifier if it hasn't received any interaction within 20 minutes of the time the last connection occurred. Now, if within your own ISAPI app, you want to keep a longer session, then you need to: 1) Decide how long a session should be, 2) Store your own SessionID cookie on the client, and set it's expiration date to (current time+timeout), 3) Check and update the same cookie with (current time+timeout) with every interaction if the same cookie is picked up on the request header. (Cont'd below) – Cahit Jan 13 '16 at 20:57
  • If you're getting a request that does not have the specific SessionID cookie, then either the cookie has expired, or the browser is not sending it. Your only option is to assume this is a new client and reissue a new SessionID cookie. (Cont'd below) – Cahit Jan 13 '16 at 21:02
  • One final note, if your code is populating the `HSE_SEND_HEADER_EX_INFO` structure, see if setting `fKeepConn` boolean to true to keep the connection active will make any difference in the behavior. I believe in most cases, this should be false. Good luck and keep us updated. – Cahit Jan 13 '16 at 21:09
  • fKeepConn is unfortunately set to true - you had be optimistic there! I'll check out the other stuff but it sounds like you've hit the nail on the head. – Ieuan Stanley Jan 14 '16 at 14:02
  • Haven't found anything yet but this seems like it's about as close to an answer as I'm going to get without opening up the entire system. Thanks! – Ieuan Stanley Jan 15 '16 at 08:49
0

Are you sure Session cookie is expiring and issue is consistent in all browsers?

I have faced some issue in which application has some fatal error or memory on server is full & AppPool crashes thus session reset itself. Please monitor server logs using Perfmon for that period, there might be some fatal error, application error, IIS error or system error.

I have struggled longtime like this at last cultprit was fatal error due to which sometimes AppPool crash & thus all application hosted on IIS using that AppPool also reset & thus session destroyed for those applications.

Pranav Singh
  • 17,079
  • 30
  • 77
  • 104
  • We thought of that unfortunately - no memory issues or crashing - the Event Log shows nothing out of the ordinary that coincides with the expiry time. Also unfortunately, we can't test the issue in any browser other than IE - the original authors didn't think that cross-browser compatibility was an issue back in 1993 and the code is ridden with IE-specific code. – Ieuan Stanley Jan 13 '16 at 09:06