2010-04-08 29 views
12

Por favor, ¿cómo evitar que múltiples usuarios inicien sesión a la vez con una identificación de usuario?En el sitio asp.net cómo prevenir múltiples inicios de sesión de la misma identificación de usuario?

Busqué en Internet y encontró algunos aspectos, pero de alguna manera que no funcionan en estas situaciones:

  1. Si Javascript en Brower se apaga.
  2. Si el usuario no hace clic en cerrar sesión y cierra directamente el navegador.

Por favor sugiero de alguna manera.

gracias

haansi

+0

posible duplicado de http://stackoverflow.com/questions/2138494/prevent-multiple-logons-for-a-single-user-in-asp-net –

Respuesta

10

Puede haber varias posibilidades. Una respuesta rápida es:

  1. Mantener un indicador en la base de datos; en cada inicio de sesión/actualización actualice la bandera. Por ejemplo, en cada solicitud de autenticación puede rechazar la solicitud de inicio de sesión si la marca ya es verdadera.

  2. Como alternativa, puede mantener una lista de usuarios en el objeto Application y usar .Contains para ver si ya existe.

--EDIT--

permite tratar la opción bandera de base de datos; y suponga que tiene un método llamado StillLoggedIn(User) que actualiza la fecha/hora y marca.

Por lo tanto, cuando los registros de usuario en:

  1. La aplicación se va a autenticar al usuario y establecer bandera = 1, y marcar una marca de fecha/hora.
  2. Para solicitudes posteriores, la aplicación llamaría al StillLoggedIn(User);

  3. Prepare un servicio de Windows que explore la base de datos de vez en cuando (digamos después de 5 minutos si tiene 10000 usuarios).El servicio compararía la fecha/hora de la base de datos con la fecha/hora actual y marcaría el indicador como 0 si currentTime menos lastUsedTime es mayor que, digamos, 5 minutos.

Podría ser cualquier cosa además de una base de datos y un servicio de Windows.

+6

Necesitará algún tipo de mecanismo de tiempo de inactividad para los usuarios que iniciaron sesión y que tampoco cerraron sesión correctamente. – Bermo

+0

hola KMan, En relación con 1. ¿Qué pasa si un usuario inicia sesión y luego cierra el navegador en lugar de cerrar la sesión? Su entrada permanecerá en DB y no podrá volver a iniciar sesión. En cuanto a 2. Si guardo la lista de usuarios en la aplicación; ¿Qué pasará si uso close broswer? Si dices después de un tiempo en particular, debería consultar a los usuarios; que por favor, ¿cómo se puede comprobar? – haansi

+0

@Haansi: Por favor, vea mi edición en respuesta a su comentario. –

1

No hay una respuesta aquí, ya que depende de cómo se autentica a los usuarios. Sin embargo, la lógica básica sería simple: cuando un usuario inicie sesión, verifique su nombre de usuario o ID con una lista de usuarios que ya hayan iniciado sesión y, si hay una coincidencia, no los autentique (y en su lugar deles algún tipo de mensaje que explique por qué no pueden iniciar sesión).

Obviamente, la manera exacta de hacerlo depende de cómo esté autenticando a los usuarios y almacenando los detalles del usuario; necesitará proporcionar más detalles si desea más ayuda.

+0

Hola Dan Diplo, Estoy autenticando usuarios de la base de datos usando identificación y contraseña. Que coloque userId en la sesión. No es problema mantener la lista de usuarios actualmente conectados; el problema es cómo rastrearlos si cierran el navegador y no se desconectan. ¿Qué sucede si el script del lado del cliente está deshabilitado en los navegadores de los visitantes? – haansi

+1

Podría establecer un tiempo de espera de sesión corto y luego manejar el evento Session_End (en global.ascx) para desconectar a los usuarios cuando la sesión expira. –

1

Miré la tabla de membresía y no vi ninguna columna como "IsLoggedIn", por lo que la API de membresía no cumple con este requisito.

Puede ser que usted puede utilizar el sistema Asp.net Cache y marcar al usuario como "LoggedIn". De esta forma puede verificar si hay inicios de sesión adicionales.

+0

hi Efe, Lis de usuarios actuales se puede mantener. El problema es cómo hacer un seguimiento de los usuarios. ¿Qué sucede si cierran el navegador y no cierran sesión? ¿Qué sucede si el script del lado del cliente está deshabilitado en los navegadores de los visitantes? – haansi

17

hemos implementado un sistema de este a lo largo de las siguientes líneas:

  • añadido una propiedad a los usuarios Perfil de mantener su ID de sesión.
  • Cada vez que un usuario inicia sesión, almacena su ID de sesión en el perfil.
  • En cualquier página que requiera este nivel de seguridad, verifique si la ID de sesión almacenada en el perfil coincide con su sesión. Esta comprobación podría realizarse en un controlador de eventos personalizado de AuthorizeRequest, o podría realizarse en una clase Base de la que estas páginas se derivan, y si no, redirigirlas a la página de inicio de sesión.

Fuimos por la opción de la clase base ya que tenemos dos niveles de autenticación:

  1. El usuario tiene un símbolo de galletas para demostrar que han entrado en algún momento en el pasado - esto está muy bien para mostrarles contenido restringido del sitio.
  2. El usuario ha proporcionado sus datos de inicio de sesión en esta sesión, esto es necesario al mostrarles cualquier información personal (direcciones de correo electrónico, preferencias, búsquedas de trabajo guardadas, etc.).

Los principales problemas que encontrará con casi cualquier sistema:

  1. Usando los usuarios de dirección IP no es fiable - los usuarios corporativos, que están detrás de proxies, etc, a menudo comparten una dirección IP, por lo que lo haría " parece "ser el mismo usuario".
  2. Confiar en que un usuario cierre la sesión no es confiable - la computadora/el navegador de los usuarios pueden fallar al no darles la oportunidad de cerrar la sesión, el usuario puede/se olvidará de cerrar la sesión.
  3. Basándose en los tiempos de espera de sesión es poco fiable - si usted no está utilizando InProc sesiones, el evento SessionEnd nunca se disparará, si el servidor se bloquea el evento no se llama, etc.

los temas que le' encontrará con una solución como la mía son:

  1. no se detiene el segundo usuario que entra - en lugar de ello se bloqueará al usuario primera, que debería desalentar el intercambio de datos en el primer lugar.
  2. Si no implementa esto como un controlador AuthorizeRequest, debe recordar realizar la comprobación en las páginas que deben bloquearse.

En respuesta a las observaciones

En respuesta a sus consultas específicas:

  1. Los default Profile Provider almacena los datos en la misma base de datos SQL como el proveedor de pertenencia (las tablas se crean junto con el tablas de membresía y roles). Si tuviera que almacenarlo "en la memoria caché", este debería ser el caché de la aplicación global, a lo largo de las líneas KMan suggests in option 2, y como se señaló en los comentarios, tendría que crear un tiempo de espera para esto, y eso nos lleva de vuelta a la cuestión de determinar esto de manera confiable.
  2. el usuario no sesión: Esto se maneja en nuestro sistema al no bloquear a futuros usuarios, pero bloqueando previamente conectado usuarios: - por lo
    • Alice llega al sitio, inicia sesión, comienza a navegar.
    • Bob llega al sitio y, al iniciar sesión con los detalles de Alice, comienza a navegar.
    • Alice intenta continuar navegando, está bloqueada, tiene que iniciar sesión de nuevo.
    • Bob ahora está bloqueado.
    • etc.

En su forma más básica, esto no va a parar a los usuarios compartir sus inicios de sesión, pero se les causar molestias, obligándolos a mantener el registro. Si es necesario se puede añadir un retraso en el proceso de inicio de sesión, por lo que si un ID de sesión diferente intenta iniciar sesión en el sitio dentro del tiempo de espera de la sesión (predeterminado de 20 minutos) o en otro momento, por ejemplo, basado en el tiempo promedio que un usuario pasa en una página, negar el intento de inicio de sesión.

+0

Hola Zhap, gracias por guiar. No he usado perfiles de usuario. Entonces hay algunos quries relevantes. 1. ¿Hay alguna ventaja de almacenar con perfiles de usuario. ¿Qué sucede si guardo estos en la base de datos o cashe, etc.? 2. ¿Cómo nos las arreglaremos si el usuario no cierra la sesión? ¿Qué pasa si el usuario solo cierra Broswer? gracias – haansi

1

Esta es la forma en que lo hago.

Una vez que la conexión del usuario, marque la bandera y Id.sesión de DB, si se encuentra conectado con la misma cuenta y diferente Id.sesión (compárese recién generado actual Id.sesión y Id.sesión de DB), alerta de usuario algo así como "sistema detecta que no cierra la sesión desde su último inicio de sesión, haga clic en < "OK"> para cerrar sesión en el último inicio de sesión y crear una nueva sesión. " Si está bien, simplemente reemplace el SessionId anterior con el SessionID actual en DB.

Una cosa más es comprobar el ID de sesión actual y el ID de sesión de la base de datos en cada página, si no es lo mismo, cerrar la sesión y redirigir a la página de inicio de sesión.

Sin importar si el usuario no cerró la sesión correctamente o simplemente cerró el navegador, el usuario tiene la posibilidad de desconectarse y no es necesario esperar hasta la finalización de la sesión de IIS. Se evitará el inicio de sesión múltiple con la misma cuenta al mismo tiempo.

Esperanza esta ayuda, gracias ...

+0

bueno, pero podría proporcionar un ejemplo de código? – toxicate20

1

Lo que hicimos es que usamos una combinación de estado de la sesión y el estado de aplicación para evitar la entrada duplicada.

Cuando un usuario inicia sesión, su userId se recupera de la base de datos de miembros asp.net y se guarda en el estado de la aplicación como un objeto único.

Dado que el estado de la aplicación es global para la aplicación y no específico para una sesión de usuario, podemos verificar si el ID de usuario ya está guardado en el estado de la Aplicación. Si ya está guardado, podemos notificar al usuario y detener el inicio de sesión. Cuando la sesión expira (en Session_End dentro del archivo Global.asax), ese objeto de estado de la aplicación para ese usuario en particular se puede eliminar del estado de la aplicación para que pueda iniciar sesión de nuevo después de que su sesión haya expirado.

Aquí está el código: En Login.aspx.cs:

protected void OnLoggingIn(object sender, LoginCancelEventArgs e) 
    { 
     // Accesses the database to get the logged-in user. 
     MembershipUser userInfo = Membership.GetUser(LoginUser.UserName); 
     UserMan.UserID = userInfo.ProviderUserKey.ToString(); 

     if (Application[UserMan.UserID] != null) 
     { 
      if (Convert.ToString(Application[UserMan.UserID]) == UserMan.UserID) 
      { 
       e.Cancel = true; 
      } 
      else 
      { 
       // Save the user id retrieved from membership database to application state. 
       Application[UserMan.UserID] = UserMan.UserID; 
      } 
     } 
     else 
     { 
      Application[UserMan.UserID] = UserMan.UserID;     
     } 
    } 

Y en Global.asax:

void Session_End(object sender, EventArgs e) 
    { 
     // Code that runs when a session ends. 
     // Note: The Session_End event is raised only when the sessionstate mode 
     // is set to InProc in the Web.config file. If session mode is set to StateServer 
     // or SQLServer, the event is not raised. 

     if (Application[UserMan.UserID] != null) 
     { 
      if (Convert.ToString(Application[UserMan.UserID]) == UserMan.UserID) 
      {      
       Application.Contents.Remove(UserMan.UserID); 
      } 
     } 
    } 

Aunque esta solución parece un poco desordenado, que funciona bastante bien sin demasiado mucha codificación y menos hits en la base de datos.

+0

¿Qué es UserMan? –

0

Zhaph - Ben Duguid, perfil de pequeña nota no se puede acceder en AuthenticateRequest ya que no se crea hasta AcquireSessionState evento de aplicación por lo que si usaran dicho enfoque (en lugar de página) Tendrían que manejar AcquireRequestState o PostAcquireRequestState

0

Cuando el miembro inició sesión. Configure un Random int ex. randNo, guardar caché [UserName] = randNo, session [UserName] = randNo. Cuando el miembro accede a cualquier página, verificamos: caché [Nombre de usuario] == La sesión [Nombre de usuario] está bien; de lo contrario, este usuario cerrará la sesión. (media: ingresa primero, cerrar sesión primero)

Cuestiones relacionadas