Here I am, back again in 2012. Today I want to show how to restrict multiple concurrent user sessions.

My approach here works for both SharePoint and ASP.NET applications.

Scenario

In SharePoint/ASP.NET web sites using Forms Authentication and Session State, when logging in, the ASP.NET grants a session to the user.

If you haven’t changed your solution, probably the same user can log in to the application simultaneously from different browsers/desktops.

This behaviour brings some security issues that you can avoid by limiting the user to one session per account.

Solution

When the user is logged in, map the session and the user ID that is established using the Application State and when the user is logged out remove this session from the mapping. Then on each request you need to intercept and validate it using a Module.

Diagram

To make it clearer, check the Sequence Diagram for this solution:

Figure 1 – Sequence Diagram

In this diagram the following users and objects are described:

Browser 1 and 2 – They represent different browsers that displays pages.

Page – Object that is requested by the browser.

httpApplication – Application State whose scope is global, at the Application level.

httpModule – Module that intercepts requests to pages.

Note: In all cases just one user (User A) is requesting pages from different browsers.

Here are the steps that describe the diagram above:

1 – First Request (from Browser 1)

In the First Request SharePoint/ASP.NET Application starts, which loads the Application State (httpApplication).

The httpModule (to be developed) is loaded by the httpApplication.

Then the initialization of the module (Init) creates a variable to store user sessions in the Application State and adds an event handler to PostAcquireRequestState event to be triggered on each request.

2 – User A Logs In (from Browser 1)

The user A logs in to the web site, and the user session (SessionContext) is mapped to the variable stored in the httpApplication.

3 – User A Logs In (from Browser 2)

The user A logs in to the web site, and the user session (SessionContext) is mapped to the variable stored in the httpApplication, which overwrites the previous user session.

4 – Request to Any Page (from Browser 1)

The user A try to get a different page, but now the user session is no longer available in the httpApplication. The SessionID stored is different from the current SessionID, so the module forces the Session to be abandoned, redirecting the user to the Login page.

5 – User A Logs Out (from Browser 2)

The user A logs out, the user session (SessionContext) is removed from the variable stored in the httpApplication and the session is abandoned, redirecting the user the Login page.

Alternative case

If the user closes the browser, the variable remains in the httpApplication and the session remains active till it expires. When the user logs in again, the variable is overwritten (case 3 above).

Code

Now that it is very clear the purpose of this solution, let’s check the code for that.

A class is created to store the Session Context of the user:

Code Snippet

using System;

namespace Core

{

publicclassSessionContext

{

publicstring UserName { get; set; }

publicstring SessionID { get; set; }

}

}

The core part of the solution is the httpModule that intercepts the requests: