2009-12-19 48 views
14

Estoy desarrollando una aplicación que necesita para evitar el inicio de sesión múltiple con el mismo nombre de usuario y contraseña.Impedir el inicio de sesión múltiple con el mismo nombre de usuario y contraseña

Si sucede en la misma máquina, entonces obviamente tenemos que hacer algo con la sesión del usuario, pero también debería evitar que se inicien sesión en máquinas diferentes con el mismo nombre de usuario y contraseña.

tenemos que mantener en cuenta lo siguiente:

  1. Si el usuario cierra el navegador sin cerrar la sesión.
  2. Si el tiempo de espera de la sesión.

Agradeceria cualquier ayuda sobre esto.

+1

¿Tiene algún tipo de sistema de almacenamiento central que está utilizando para el seguimiento de los datos de usuario/sesión? Si es así, ¿qué es? – GrayWizardx

+0

¿Está utilizando el marco de seguridad de Spring? O ha implementado el suyo propio. ¿Esta pregunta está cerrada? – Ameya

Respuesta

3

Tome un campo adicional en la tabla con el nombre de columna diga "IsLoggedIn" como campo de bit y establézcalo en verdadero hasta que el usuario inicie sesión. Tan pronto como el usuario cierre la sesión, configúrelo en falso. Esto debe hacerse también para el tiempo de caducidad de la sesión. Tan pronto como la sesión expira este campo debe establecerse en falsas de forma automática mediante disparadores oa través de llamada SP

buena solución sigue siendo la bienvenida

+0

Sr. Shantanu Gupta, Esto parece ser posible. Pero antes de implementar me gustaría saber cómo obtener un evento que proporcionará que la sesión haya expirado. Ayuda. – vivmal

+1

en la configuración del servidor u necesita configurar la hora de caducidad de la sesión, tan pronto como su sesión se anule y se guarde en la base de datos, puede configurar la variable IsLoggedIn como falsa y restablecer el campo de sesión. Para aplicaciones web usualmente no necesita el campo IsLoggedIn ya que su campo de sesión muestra que si el campo Session no es nulo, entonces un usuario ya ha iniciado sesión pero bajo la aplicación de ventana no hay concepto de sesión, entonces en ese caso puede usar arriba método mencionado –

+0

Vaya a través del enlace para obtener más información sobre cómo usar la variable de sesión. http://techpint.com/programming/how-create-session-variable-aspnet –

0

Me seguimiento de la última dirección IP conocida de cada usuario y una marca de tiempo para cuando fueron los últimos en esa IP. Luego, puede bloquear el acceso de otras direcciones IP durante 5 minutos, una hora o lo que quiera.

Cada vez que cambia la dirección IP, puede a) caducar la sesión anterior del usuario, por lo que se ven obligados a volver a iniciarla yb) incrementar un contador por usuario (que puede poner a cero cada hora). Si el contador supera los 5 (o algo así), puede bloquear todo el acceso a la cuenta del usuario durante un período de tiempo más largo.

+3

Debido a NAT y la asignación dinámica de IP, cualquier solución que dependa de las direcciones IP causará problemas y aconsejaría que no lo haga. –

+0

Si la IP de su usuario habitual cambia 5 veces en una hora, entonces sí. Ve por otra cosa. – ojrac

0

Puede almacenar algún tipo de id de sesión para el usuario al iniciar sesión. Cuando el usuario cierra la sesión o cuando la sesión caduca, se elimina esa información nuevamente.

Cuando un usuario intenta iniciar sesión y usted ya tiene un ID de sesión almacenado para este usuario, permita que el usuario lo confirme y luego invalide la sesión anterior.

Un usuario seguramente querrá iniciar sesión de nuevo inmediatamente si el navegador se bloqueó o algo así, por lo que dejar que el usuario espere a que expire la sesión podría ser molesto.

¿Tiene sentido para su aplicación?

+0

Sr. Peter Lang, Creo que la identificación de sesión solo se puede mantener desde el lado del cliente/navegador. ¿Qué pasará si dos usuarios comparten los mismos datos de inicio de sesión pero están sentados en máquinas diferentes? Ayuda. – vivmal

+0

¿No puede asignar y devolver una identificación de sesión en el servidor al iniciar sesión? ¿Cuál es la razón por la que dos usuarios comparten los mismos datos de inicio de sesión? –

+0

Podemos tomar un campo adicional (LoggedIn) en la tabla de la base de datos y hacer que sea verdadero o falso cuando alguien inicia o cierra la sesión. ¿Cómo podemos asignar la id de la sesión en el servidor cuando algún usuario inicie sesión? Por favor hazme saber Gracias por adelantado. – vivmal

2

También recomendaría la solución de Shantanu Gupta: tenga una columna de base de datos que indique que el usuario está actualmente conectado y actualice esa columna en consecuencia.

Con el fin de 'captura' la caducidad de sesión, es necesario definir en su web.xml:

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

Dónde MySessionListener es su implementación de la interfaz HttpSessionListener (proporcionado por el Servlet API).

23

Si el usuario cierra el navegador sin cerrar sesión.

En particular, este caso es difícil y no es confiable para detectar. Puede utilizar el evento beforeunload en Javascript, pero depende totalmente de si el navegador tiene habilitado JS y si el navegador en particular admite este evento no estándar (por ejemplo, Opera no). Esa es también una de las principales razones por las que sugiero simplemente desconectarse del usuario que inició sesión previamente en lugar de evitar el inicio de sesión. Eso también es más fácil de usar y seguro para el caso de que el usuario "olvide" cerrar la sesión desde la otra computadora.

La manera más fácil es dejar que el User tienen una variable static Map<User, HttpSession> y se deja poner en práctica HttpSessionBindingListener (y Object#equals() y 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); 
    } 

} 

Cuando vuelve a entrar la User de la siguiente manera:

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

entonces se invocará el valueBound() que eliminará cualquier previamente el usuario conectado en el mapa de logins e invalidar la sesión.

Al cerrar la sesión del User de la siguiente manera:

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

o cuando la sesión se mide el tiempo hacia fuera, entonces el valueUnbound() se invocará que elimina el usuario del mapa logins.

+1

+1 imho, este es el caso de uso más complicado. tiene sentido desconectarse del usuario anterior, de lo contrario tendrá que esperar hasta que las sesiones se agote el tiempo de espera antes de que pueda iniciar sesión de nuevo. – aldrin

+0

Acepto: muchos usuarios cerrarán una pestaña/ventana en lugar de hacer clic en un botón de cerrar sesión, y esperar a que la sesión termine sería realmente molesto. – tofarr

+0

Estoy leyendo esto y estoy confundido sobre el Mapa de usuarios. ¿La clase de usuario es ApplicationScoped? ¿También es solicitar una instancia de HttpRequest? –

2

Simplemente sugeriría usar un marco de seguridad para manejar todos estos detalles por usted. Spring Security, por ejemplo, es bastante fácil de integrar en un proyecto existente, se puede personalizar bastante si es necesario, y lo más importante es que tiene soporte integrado para detectar y controlar inicios de sesión concurrentes.

No reinvente la rueda cuando no la necesite, de lo contrario terminará gastando un buen tiempo para crear una rueda con baches.

0

Esto se puede aplicar fácilmente si tiene una sesión. Para cada inicio de sesión del navegador, debe crear un registro de sesión en la sesión DB. El ID de sesión se puede usar como cookie de autenticación. La sesión DB también tiene un índice con nombre de usuario. Al iniciar sesión, puede consultar la base de datos para verificar cuántas sesiones hay. De hecho, permitimos una sesión para cada tipo. Por ejemplo, el usuario puede tener un inicio de sesión desde un teléfono móvil y otro desde el navegador. Pero no puede tener 2 sesiones de navegador.

Para resolver el problema que mencionaste. Tiene 2 opciones,

  1. Tenga un tiempo de espera de sesión muy corto (como 5 minutos) y amplíe la sesión en cada uso. De esta forma, el usuario se cerrará automáticamente si se va sin cerrar la sesión.

  2. Golpee la otra sesión. La nueva sesión choca con la sesión anterior. La sesión golpeada permanece en DB con una bandera especial durante 24 horas. Mostramos un mensaje para decirle al usuario que la otra sesión está siendo golpeada y muestra la hora y el IP. De esta manera, el usuario recibirá una notificación si su cuenta se ve comprometida.

4

Crear una tabla en la base de datos — llamémoslo [online_users] — con tres campos:

[online_users] 
1. username 
2. login_time 
3. logout_time 

Cada vez que un usuario se conecta, introduzca el nombre del usuario y el momento de inicio de sesión en [online_users].

En todas las páginas que requieren que los usuarios inicien sesión, establezca esta condición: marque [online_users] para ver si el logout_time del usuario está en blanco o no.

Cada vez que un usuario presiona un botón de cierre de sesión, establezca la logout_time en [online_users] para el nombre de ese usuario.

Si alguien intenta iniciar sesión con un nombre de usuario y contraseña activa, la verificación de username y logout_time y mostrar un mensaje que indica que el usuario ya está conectado. Y, lo más importante, establece logout_time a MULTIPLELOGIN para ese usuario.

Si ese usuario está conectado en cualquier otra máquina, entonces si actualiza o navega a otra página, el sitio le dirá que ha cerrado la sesión. Luego, el usuario puede ser redirigido a la página de inicio del sitio.

0

he implementado una posible solución para mí,

en el loginFilter utilizo, me puse un lastloggedin, userloggedin y UserSession dentro del registro de usuario en mi sistema.

  user.setUser_lastlogged(new Date()); 
      user.setUser_loggedin(true); 
      user.setSessionId(request.getSession().getId()); 
      appService.saveUsers(user); 

así que cuando voy a cualquiera de mis acciones de struts2 tengo un fragmento de código en el método de preparación.

@Override 
public void prepare() throws Exception { 
    UsersBase usercheck = appservice.getUserByUsername((String)request.getSession().getAttribute("j_username")); 
    if(request.getSession().getId().equals(usercheck.getSessionId())){ 
     request.getSession().invalidate(); 
    } 

} 

Esto registrará el usuario a cabo al iniciar la sesión en otra máquina, o si no desea que los registre en lo que podía hacer lo siguiente en la loginFilter

UsersBase userdto = appService.getUserByUsername(username); 
     if (userdto != null) { 
      if ((userdto.getUser_loggedin())) { 
       if (request.getSession().getId().equals(userdto.getSessionId())) { 
        authRequest.eraseCredentials(); 
        request.getSession().setAttribute("error", "You are already logged in "); 
       } 
      } 
     } 
2

Tal vez excesivamente simplificada, pero bueno ... me funciona en Web2Py:

Solo en el inicio de sesión exitoso, escribo el SessionID (response.session_id) en la tabla auth_membership. En la página de inicio (página de índice) compruebo si el response.session_id actual es igual al SessionID que proviene de la base de datos. Si es así, todo está bien. Si no, (el usuario "mayor") se cierra la sesión cortésmente.

Lo anterior funciona ya que con cada inicio de sesión se crea y almacena un nuevo response.session_id en la base de datos. La comprobación se realiza solo en la página de destino (que en mi aplicación es la más importante, inicia muchas otras funciones), por lo que no hay demasiados resultados de DB para lo anterior. Lo anterior no depende de que el usuario cierre la sesión. No se trata de una dirección IP (que otros han mencionado, sufre de sus propios problemas) Permite que solo un usuario inicie sesión a la vez y cierra la sesión del usuario "anterior".

creo que sirve NeoToren

Cuestiones relacionadas