How to allow only one user per account in ASP.NetTags: asp.net, web, csharp — 25th of September 2009

Why?

Usually this is used for making sure people aren't sharing their account. If I give my buddy my account and he logs in while I'm using it, I get kicked out!

The Idea

Whenever a user logs in to their account we store their username along with their Session ID. The next time someone that is logged in tries to make a request, we check if their Session ID matches with the Session ID we stored for them. If it's a mismatch, that means someone else logged in after them! Thus we can safely log them out.

The Implementation

We'll make use of 3 things.
  • Session ID: Allowing us to distinguish someone's browsing instance
  • Global.asax: To grab the Session End Event
  • One Storage Location:
    • HttpContext.Current.Application
    • Database

If your website is running on one server, then you can just use Application, but if its running on multiple you'll have to go for the Database. The code shows it being done for Application.
When the user logs in you need to store the session id:
UserAccout ua = GetUserAccount();
HttpContext.Current.Application["usr_" + ua.UserName] = HttpContext.Current.Session.SessionID;
And when they log out we need to clear it:
UserAccout ua = GetUserAccount();
HttpContext.Current.Application.Remove("usr_" + ua.UserName);
In your Global.asax file you should call the same Logout code to clean up when their Session Ends
void Session_End(object sender, EventArgs e)
{
    UserAccout ua = GetUserAccount();
    if (ua != null)
    {
        HttpContext.Current.Application.Remove("usr_" + ua.UserName);
    }
}
And now that we need to actually check if a user should be kicked out or not, so execute this in the beginning of all requests:
UserAccout ua = GetUserAccount();
if (!HttpContext.Current.Application["usr_" + ua.UserName].Equals(HttpContext.Current.Session.SessionID))
{
    Logout();
    HttpContext.Current.Response.Redirect("SignOut.aspx");
}