8

I have the code below on a login page. I'm using this to set the login timeout by customer. In IE8 I'm running into the problem that if a user opens another browser window, then logs out in the first window, when they relog back in they get bounced back to the login after a single page (every time). If they don't open another browser, everything is fine.

I've found ALOT of questions about this, but the only solution I've found that works is to use the cookieless method (URI).

I've seen a few articles saying to set the domain, which I'm doing, but that doesn't work. Also, I've tried setting the authticket to both persistent and non-persistent. Neither has made a difference. I have seen that once the auth cookie is gone from the folder, it doesnt get recreated when I log in.

If I open that second browser window as a "New Session" I don't have any problems. (This isn't practical as we cant train every user of the app to open any additional windows this way.)

Is there a fix for this that anyone has found that doesn't involves using the cookieless URI approach?

int timeoutValue = 20 // This value is actually returned from a method;

FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(LoginControl.UserName, false, timeoutValue);            
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);

HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);                 
authCookie.Domain = "my.domain";
authCookie.Expires = DateTime.Now.AddMinutes(timeoutValue);

HttpContext.Current.Response.Cookies.Add(authCookie);
Mikejh99
  • 378
  • 5
  • 12
  • clarify: the user opens a new browser window from the app? i.e. right-click>open link in new window, essentially extending the session to the new window? – Sky Sanders Feb 11 '10 at 14:34
  • Yes, but it doesn't matter how they open the second window. If they start a new browser from a desktop shortcut, new tab, right-click. The only way that doesn't cause the problem is "File... New Session" – Mikejh99 Feb 11 '10 at 16:03
  • Actually, let me restate that. If I start the orignal browser from a shortcut on the desktop, I do not have the issue. I think this has something to do with the way IE is launching, with -nomerge or something like that. – Mikejh99 Feb 11 '10 at 17:13
  • Let's try to debug this. In global.asax Application_AuthenticateRequest enumerate all cookies HttpContext.Current.Request.Cookies and log them all to some file (logging to file should be done inside lock(){}). On Application_EndRequest log HttpContext.Current.Response.Cookies. Post here logs for relogin with just one page and for buggy relogin with another browser window. – Dmitry Osinovskiy Feb 15 '10 at 17:24

2 Answers2

3

This a "feature" of Internet Explorer to share cookies/session across browser windows. Hence the new "feature" to create a "New Session" in IE8. Therefore I do not believe there is any ideal way of easily stopping this behaviour.

Other than going cookieless of course.

BlackMael
  • 3,198
  • 5
  • 25
  • 42
2

I know this is a old question, but I have been battling this same problem and I believe I have a fix. I have replicated these exact symptoms and have also been able to successfully eliminate them (at least so far).

Only putting an expiration on the cookie if you want a persistent auth ticket is eliminating the problem for me.

Here is my method as it now stands:

internal static void CreateAuthenticationCookie(string userName, bool rememberMe, bool expired = false)
{
    int timeout = expired ? -1440 : (rememberMe ? 43200 : 20); // Timeout in minutes, 525600 = 365 days, 1440 = 1 day.
    FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, userName, DateTime.Now, DateTime.Now.AddMinutes(timeout), rememberMe, string.Empty);
    string encrypted = FormsAuthentication.Encrypt(ticket);
    var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encrypted);

    if (rememberMe)
        cookie.Expires = System.DateTime.Now.AddMinutes(timeout);

    HttpContext.Current.Response.Cookies.Add(cookie);
}

And here is how I call it:

if(createPersistentCookie)
    CreateAuthenticationCookie(userName, createPersistentCookie);
else
    FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);

I realize that by the way I am calling it, there is no need for the "remember me" parameter on the CreateAuthenticationCookie method (since I always pass true in that case), but I haven't refactored it yet and it better demonstrates how someone else may want to use it.

I wanted a way to easily have a sliding expiration if the user chose to not "remember me", but if they did choose "remember me" I didn't want to be constrained to the 30 minute timeout of my non "remember me" users. My purpose was so that if someone is using a public computer they get the sliding expiration plus no remember me, but if they are using a personal computer they can "remember me" and not be constrained by the timeout setting in the web.config. Don't know that this all applies to your situation, but I am hoping it helps someone or that my methodology can draw some constructive criticism so that I can make adjustments if needed.

PS. Here are my web.config settings for forms authentication:

<authentication mode="Forms">
      <forms loginUrl="~/Account/LogOn" timeout="30" slidingExpiration="true"/>
</authentication>
Quesi
  • 746
  • 6
  • 16