I recently received an email from a developer who needed to implement a behavior around a user’s session timeout behavior.

As you probably know, we can configure our application to “expire” a user’s session at any interval that we wish.

Example:

<system.web>
<sessionState timeout="10" />
........
</system.web>

We can add a specification to our application’s web.config file to change the default session expiration time from 20 minutes to a time span of our own choosing. (10 minutes in the example above.)

The session timeout value is a sliding value; on each request the timeout period is set to the current time plus the timeout value.

This means that if a user submits a request after the timeout period expires, the session will have been terminated and the user will no longer be authenticated. If the user’s “post-back” is requesting a secured resource, they will be redirected to the “login” page since the application sees this request as from an anonymous user. (When a session expires the user is de-authenticated.)

The problem in this cast is that the application requirements required that the user be AUTOMATICALLY redirected when the session times out.

This is a sound security practice in certain applications.

For example, lets suppose the application’s user has displayed the results of a query of “sensitive” information. If the user then walks away from their PC, that sensitive data will stay displayed indefinably.

The application that I was contacted about needed the user’s browser to be automatically be redirected when the session timed out.

The problem, of course, is that browser based applications are innately stateless sine they run on HTTP ( a stateless protocol). The browser (client) and the sever only communicate when the CLIENT specifically makes a request of the server.

To meet the applications requirements we can add a timer in JavaScript to be run in the browser.

In our master page (so that the JavaScript will be included in, and executed by every page in our application) we can include the following client side script:

   1:  <head runat="server">
   2:      <title></title>
   3:      <link href="~/Styles/Site.css" rel="stylesheet" type="text/css" />
   4:      <script type="text/javascript" language="javascript">
   5:      <!--
   6:              var secs
   7:              var timerID = null
   8:              var timerRunning = false
   9:              var delay = 1000
  10:   
  11:              function InitializeTimer() 
  12:              {
  13:                  if (typeof HeadLoginName != 'undefined') {
  14:                  // Set the length of the timer, in seconds
  15:                  secs = 630
  16:                  StopTheClock()
  17:                  StartTheTimer()    
  18:                  }
  19:              }
  20:   
  21:              function StopTheClock() 
  22:              {
  23:                  if (timerRunning)
  24:                      clearTimeout(timerID)
  25:                  timerRunning = false
  26:              }
  27:   
  28:              function StartTheTimer()
  29:              {
  30:                  if (secs == 0) 
  31:                  {
  32:                      StopTheClock()
  33:                      window.location = "default.aspx"
  34:                  }
  35:                  else 
  36:                  {
  37:                      self.status = secs
  38:                      secs = secs - 1
  39:                      timerRunning = true
  40:                      timerID = self.setTimeout("StartTheTimer()", delay)
  41:                  }
  42:              }
  43:      //-->
  44:      </script>
  45:   
  46:      <asp:ContentPlaceHolder ID="HeadContent" runat="server">
  47:      </asp:ContentPlaceHolder>
  48:  </head>

Then we add an “onload” to our html body tag as so:

<body onload="InitializeTimer()">

Note that the client side timer is set to 10 minutes and 30 seconds. This is a plus 30 second complement to the server side setting of 10 minutes so that we should be sure that when the client code “times out” the session on the server will have already expired.

When the client side timer counts down to zero this line of JavaScript code:

  33:                      window.location = "default.aspx"

causes the browser to request the application’s default page.

We could, of course, just post back to the “current” page and let the application’s authentication configuration redirect the user to the application’s login page.

Note that this method is a loose synchronization of the applications session. If we absolutely needed an exact synchronization we could implement an AJAX service method and query the server as to whether or not the REAL .NET session has expired, but we’re not going to do that here since it creates some unnecessary (for most applications)  http traffic.

We could of course do other things form our client side code and do things like black the browser window and pop up a dialog (like a screen saver) or really whatever we want. jQuery is great for this kind of powerful client side work.

Here is a quick bit of sample code that shows the technique – [ DOWNLOAD HERE ].

 

Technorati Tags: ASP.NET Sessions Tips & Tricks