tags:

views:

1112

answers:

7

I am developing an application that needs to prevent multiple login using the same user name and password.

If it happens on the same machine then obviously we need to do something with the user session, but it should also prevent if they are login on different machines using the same user name and password.

We have to keep following things in mind:

  1. If user close the browser without logout.
  2. If session time out.

I would appreciate any help on this.

+2  A: 

Take one extra field in table with the column name say "IsLoggedIn" as bit field and set it to true until the user is logged in. As soon as user logs out set it to false. This need to be done for session expiry time also. As soon as the session expires this field should be set to false automatically using triggers or thru SP call

good solution is still welcome

Shantanu Gupta
Mr. Shantanu Gupta,This seems to be achievable. But before implemeting I would like to know how to get an event that will provide that session has expired. Help.
vivmal
under server configuration u need to set session expiry time, as soon as your session xpires which is stored under database u can set IsLoggedIn variable to be false and reset session field. For web applications u usually dont need IsLoggedIn field as ur session field itself depicts that if Session Field is not Null then a user is already logged in but under window application there is no concept of session, so in that case u can use above mentioned method.
Shantanu Gupta
Go thru the link for more details on how to use session variable.http://techpint.com/programming/how-create-session-variable-aspnet
Shantanu Gupta
A: 

I'd track each user's last known IP address and a timestamp for when they were last on that IP. Then you can just block access from other IPs for 5 minutes, an hour, or whatever you like.

Whenever the IP address switches, you can a) expire the user's old session, so they're forced to log back in and b) increment a per-user counter (which you can zero out every hour). If the counter goes above 5 (or something), you can block all access to the user's account for a longer period of time.

ojrac
Due to NAT and dynamic IP allocation, any solution that depends on IP addesses will cause problems and I would advise against it.
Michael Borgwardt
If your usual user's IP changes 5 times in an hour, well then yes. Go for something else.
ojrac
A: 

You could store some sort of session-id for the user when logging in. When the user logs out or when the session expires, you remove that information again.

When a user tries to log in, and you already have a session-id stored for this user, let the user confirm that, and then invalidate the old session.

A user will certainly want to login again immediately if the browser crashed or something like that, so letting the user wait for the session to expire might be annoying.

Does this make sense for your application?

Peter Lang
Mr. Peter Lang,I believe session-id can only be maintained at client side/browser end. What will happen if two users are sharing the same login details but sitting on different machines ?Help.
vivmal
Cant't you assign and return a session-id at the server on login? What is the reason for two users sharing the same login details?
Peter Lang
We can take an extra field (LoggedIn) in database table and make it true or false when someone login or logout. How can we assign the session-id at server when some user will login. Please make me aware. Thanks in advance.
vivmal
By using $Session['Id'] at aspx page u can retrieve the session id at the page, for that u need to create a session first. http://techpint.com/programming/how-create-session-variable-aspnet
Shantanu Gupta
A: 

I would also advise for Shantanu Gupta's solution - have a database column indicating the the user is currently logged, and update that column accordingly.

In order to 'capture' session expiration, you need to define in your web.xml:

<listener>
   <listener-class>com.foo.MySessionListener</listener-class>
</listener>

Where MySessionListener is your implementation of the HttpSessionListener interface (provided by the Servlet API).

Bozho
+1  A: 

If user close the browser without logout.

Particularly this case is hard and not reliable to detect. You could use the beforeunload event in Javascript, but you're fully dependent on whether the browser has JS enabled and the particular browser supports this non-standard event (e.g. Opera doesn't). That's also one of the major reasons that I'd suggest to just logout the previously logged in user instead of preventing the login. That's also more user-friendly and secure for the case that the user "forgot" to logout from the other computer.

Easiest way is to let the User have a static Map<User, HttpSession> variable and let it implement HttpSessionBindingListener (and Object#equals() and Object#hashCode()).

public class User implements HttpSessionBindingListener {

    // All logins.
    private static Map<User, HttpSession> logins = new HashMap<User, HttpSession>();

    // Normal properties.
    private Long id;
    private String username;
    // Etc.. Of course with public getters+setters.

    @Override
    public boolean equals(Object other) {
        return (other instanceof User) && (id != null) ? id.equals(((User) other).id) : (other == this);
    }

    @Override
    public int hashCode() {
        return (id != null) ? (this.getClass().hashCode() + id.hashCode()) : super.hashCode();
    }

    @Override
    public void valueBound(HttpSessionBindingEvent event) {
        HttpSession session = logins.remove(this);
        if (session != null) {
            session.invalidate();
        }
        logins.put(this, event.getSession());
    }

    @Override
    public void valueUnbound(HttpSessionBindingEvent event) {
        logins.remove(this);
    }

}

When you login the User as follows:

User user = userDAO.find(username, password);
if (user != null) {
    request.getSession.setAttribute("user", user);
} else {
    // Show error.
}

then it will invoke the valueBound() which will remove any previously logged in user from the logins map and invalidate the session.

When you logout the User as follows:

request.getSession().removeAttribute("user");

or when the session is timed out, then the valueUnbound() will be invoked which removes the user from the logins map.

BalusC
+1 imho, this is trickiest use case. makes sense to log out the previous user, else you will have to wait till the sessions times out before you can log in again.
aldrin
A: 

I would simply suggest using a security framework to handle all these details for you. Spring Security, for example, is fairly easy to integrate into an existing project, can be customised quite heavily if needs be - and most importantly, it has built-in support for detecting and controlling concurrent logins.

Don't reinvent the wheel when it's not needed, else you'll end up spending a good bit of time to create a bumpy wheel.

Andrzej Doyle
A: 

This can be easily enforced if you have session. For each browser login, you should create a session record in session DB. The session ID can be used as authentication cookie. The session DB also has an index with username. At login, you can query the database to check how many sessions are there. We actually allows one session for each type. For example, user can have a login from mobile phone and another one from browser. But it can't have 2 browser sessions.

To solve the problem you mentioned. You have 2 options,

  1. Have a very short session timeout (like 5 minutes) and extend session on every use. This way, user will be automatically logged out if leaving without logging out.

  2. Bump the other session. The new session bumps the old session. The bumped session stays in DB with a special flag for 24 hours. We display a message to tell user the other session is being bumped and displays time and IP. This way, user will get notified if their account is being compromised.

ZZ Coder