Tuesday, 16 April 2013

Detecting asp.net session timeouts

A common requirement i get in alot of asp.net applications to automatically redirected to a login page or a home page when my ASP.Net session times out and the user tries to hit a page in the website.

Before i mention the code , it is important to note that every asp.net application you install on your IIS server gets the same session cookie id by default : a cookie called:ASP.NET_SessionId

To establish this , go to IIS , highlight your website , ensure that Features view is on and click on the Session State icon.



Go to the Cookie settings section and you'll se that your webapplication has a cookie name/id of ASP.NET_SessionId. If you install another application , it will get the same id.




So in order to detect when the session has ended you can override the onInit method in your master page and add the following code:

/// <summary>

/// Check for the session time out

/// </summary>

/// <param name="e"></param>

protected override void OnInit(EventArgs e)
{

base.OnInit(e);

if (Context.Session != null)
{

//check whether a new session was generated

if (Session.IsNewSession)
{

//check whether a cookies had already been associated with this request

HttpCookie sessionCookie = Request.Cookies["ASP.NET_SessionId"];

if (sessionCookie != null)
{

string sessionValue = sessionCookie.Value;

if (!string.IsNullOrEmpty(sessionValue))
{

// we have session timeout condition!
Response.Redirect(
"MyhomePage.aspx");
}


Session Isolation

This is all well and good , but seeing as every .NET application gets the same cookie id on the same iis box , it is clear that this would cause unpredictable results in the scenario that you would have two or more .NET applications installed on the same server and want to detect the session timeouts in each.

In order to do this we would need to ensure session isolation. One solution to this would to put each .NET application in a different app pool. This would create the isolation needed to allow thier sessions to work independantly to each other.

If this isn't an option , another way to do it is to specify a unique session cookie Id for each .NET application in their web.configs. This can be either done manually in the web.config or can be programatically achived by Creating customized Setup projects in Visual Studio 2008/2010.

To Manually add a unique cookie to your web.config , add the cookieName attribute to your sesssionstate element. It's good practice to give this your application name. If you have multiple versions of the sample application installed on your iis box you can configure this via the a customized setup project to create the cookie based on application name and version so you get a unique cookieName.

sessionState mode="InProc" cookieName="MyCompany.MyFinancialWebsite" timeout="15" />


/// <summary>

/// Handles the Start event of the Session control.

/// </summary>

/// <param name="sender">The source of the event.</param>

/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>

protected void Session_Start(object sender, EventArgs e)
{


SessionStateSection sessionStateSection =
(System.Web.Configuration.
SessionStateSection)

ConfigurationManager.GetSection("system.web/sessionState");

string cookieName = sessionStateSection.CookieName;

//Detect session timeout and re-direct to home page

string request_cookies = Request.Headers["Cookie"];

if ((null != request_cookies) && (request_cookies.IndexOf(cookieName) >= 0))
{


////cookie existed, so this new one is due to timeout.

////Redirect the user to the default page
Response.Redirect(
"AccountSearch.aspx?Timeout=true");
}


}

No comments:

Post a Comment