Well, your first approach should be to make sure your boss realises it's a dumb requirement (though I wouldn't necessarily put it in those words), and if it comes from a client, get your boss to have the same discussion with the person who put it in the specification. By far the best solution here is if you can persuade the customer that they don't actually want this 'feature' at all. Even if you're a newbie or new to the company, don't be intimidated out of at least raising the point. If you try that and you really can't get it removed, the logic goes something like this (in the login attempt script, once authorisation has been checked and you are about to log in) – pseudocode only, if that wasn't obvious:
string sid = DBQuery("select lastsessionid from user where userid=(ID)", userid);
Session session = GetSession(sid);
if(IsValidSession(session)){
// Already a non-expired session for this user
// Close the other session
session.Logout();
}
thisSession["user"] = userData; // or however you record that this is a logged in session
// record this as the current session for the user
DBQuery("update user set lastsessionid=(sessID) where userid=(ID)", thisSession.ID, userid);
I think it's better to kill any previous sessions rather than reject the login, otherwise it's way too easy to lock yourself out for the session expiry timeout (turn off machine at work without pressing 'Logout' link and go home/to lunch/etc) or, if there is some AJAX that keeps the session alive indefinitely, permanently. I haven't tried to do this with ASP.net so I'm not sure how easy it is to get hold of session objects for sessions other than the one you're currently in. You need to be able to do that because otherwise you won't be able to tell when a previous session has expired. session.Logout is a placeholder for clearing whatever you put into the session on login (so the next page load in that session is as a guest). Again, with ASP.net's role management that might be more tricky than it should be.