:::: MENU ::::

Friday, July 18, 2008

We have an old .NET 1.1 web application which I have to support and a recent change in the login process for a select few customers has been causing haywire with every users session. The folks at QA have been giving me a really hard time lately with this bug and I just couldn't get around as to what was causing this weird behavior.

The problem was that if we set the forms authentication and session timeouts to 10 minutes and after the 10th minute the user clicked on any link the app would redirect the user to the login page but the session was not abandoned i.e. the forms authentication ticket had expired but not the session state timeout. To make matters worse I was unable to reproduce it on DEV or QA instance with my automated test script but was able to reproduce it by manually following the steps.

After a lot of googling I finally realized the solution was right there and I had just overlooked it. The problem was in the way timeouts work for authentication tickets vs session state.

Forms authentication ticket can time out in two ways. The first scenario occurs if you use absolute expiration. With absolute expiration, you set an expiration of 20 minutes, and a user visits the site at 2:00 PM. The user will be redirected to the login page if the user visits the site after 2:20 PM. Even if the user visited some pages in between 2:00 PM and 2:20 PM the user will still be redirected to the login page after 2:20 PM.

Now if you are using sliding expiration for forms authentication and session state the scenario gets a bit complicated. With sliding expiration the session state timeout is updated on every visit but the cookie and the resulting authentication ticket are updated if the user visits the site after the expiration time is half-expired.

For example, you set an expiration of 20 minutes for forms authentication ticket and session state and you set sliding expiration to true. A user visits the site at 2:00 PM, and the user receives a cookie that is set to expire at 2:20 PM. The authentication ticket expiration is only updated if the user visits the site after 2:10 PM. If the user visits the site at 2:08 PM, the authentication ticket is not updated but the session state timeout is updated and the session now expires at 2:28 PM. If the user then waits 12 minutes, visiting the site at 2:21 PM, the authentication ticket will be expired and the user is redirected to the login page, but guess what, the session timeout has not yet expired.

Here is the MSDN link which explains this http://support.microsoft.com/kb/910439

So, how do we synch these two timeouts? Or force the other to timeout if one of them expires? The workaround we came up with was to set the authentication timeout to double the value of session timeout and have the following code in the global.asax.cs.

protected void Application_AcquireRequestState(object sender, SystemEventArgs e) 
{

    if
(Session!= null && Session.IsNewSession)
    {
       
string szCookieHeader= Request.Headers["Cookie"];
       
if((szCookieHeader!= null)&& (szCookieHeader.IndexOf("ASP.NET_SessionId")>= 0))
        {
           
if(User.Indentity.IsAuthenticated)
            {
                FormsAuthentication.SignOut();
                Response.Redirect(Request.RawUrl);
            }
        }
    }
}

 

More

Categories: