Enviar respuesta 
 
Calificación:
  • 2 votos - 4 Media
  • 1
  • 2
  • 3
  • 4
  • 5
Log out (Como seguir la pista e invalidar todos los HttpSession)
JD19 Sin conexión
mata tigres
*

Mensajes: 11
Registro en: Oct 2011
Reputación: 0
Mensaje: #1
Log out (Como seguir la pista e invalidar todos los HttpSession)
Profesor nos puede indicar la forma adecuada para realizar el log out de todos los usuarios. recuerde que por ahora lo único que se esta haciendo es limpiar la tabla hash que existe en en HibernateConnector y así eliminar el sessionBean en cargado de la session de aplicacion.
(Este mensaje fue modificado por última vez en: 13-07-2012 07:57 PM por demian.)
12-07-2012 09:08 AM
Encuentra todos sus mensajes Cita este mensaje en tu respuesta
demian Sin conexión
Administrator
*******

Mensajes: 1.808
Registro en: Jun 2010
Reputación: 0
Mensaje: #2
RE: Log out
Les dejo mi implementación del logout. Lo probé y me funciona bien. Realmente lo que hace el código seguir la pista a todas las sesiones e invalidarlas cuando invocan un método en particular. El código no es particular a CLEDA realmente, debería funcionar en general en cualquier aplicación basada en Servlets.

Es posible que quizá exista alguna implementación alternativa o una forma más sutil de hacerlo. Por ahora y para lo que necesitamos es aceptable. Como estamos usando repositorios distintos para el código van a tener que mezclar a mano:

1) Hay que hacer un HttpSessionListener, les copio mi clase completa, la puse en CledaEcho, del código pueden deducir en que paquete:

Código:
package com.minotauro.echo.app;

import java.util.HashSet;
import java.util.Set;

import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

/**
* @author Demián Gutierrez
*/
public class SessionTrackerListener implements HttpSessionListener {

  // --------------------------------------------------------------------------------
  // all this boilerplate might not be necessary, but just in case...
  // --------------------------------------------------------------------------------

  private static final Boolean MUTEX = new Boolean(true);

  // --------------------------------------------------------------------------------

  private static SessionTrackerListener instance;

  // --------------------------------------------------------------------------------

  public SessionTrackerListener() {
    synchronized (MUTEX) {
      if (instance != null) {
        throw new IllegalStateException("instance != null");
      }

      instance = this;
    }
  }

  // --------------------------------------------------------------------------------

  public static SessionTrackerListener getInstance() {
    synchronized (MUTEX) {
      if (instance == null) {
        throw new IllegalStateException("instance == null");
      }

      return instance;
    }
  }

  // --------------------------------------------------------------------------------
  // now the functionality...
  // --------------------------------------------------------------------------------

  private Set<HttpSession> httpSessionSet = new HashSet<HttpSession>();

  // --------------------------------------------------------------------------------

  @Override
  public synchronized void sessionDestroyed( //
      HttpSessionEvent evt) {
    httpSessionSet.remove(evt.getSession());
  }

  @Override
  public synchronized void sessionCreated( //
      HttpSessionEvent evt) {
    httpSessionSet.add(evt.getSession());
  }

  // --------------------------------------------------------------------------------

  public synchronized void invalidateAllSessions() {
    HttpSession[] httpSessionArray = //
    httpSessionSet.toArray(new HttpSession[0]);

    for (HttpSession httpSession : httpSessionArray) {
      httpSession.invalidate();
    }
  }
}

2) Luego hay que registrar el filtro en el web.xml, el mío quedó así:

Código:
<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <listener>
        <listener-class>com.minotauro.echo.app.SessionTrackerListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>AppServlet</servlet-name>
        <servlet-class>com.minotauro.sandbox.app.AppServlet</servlet-class>
    </servlet>

    <servlet>
        <servlet-name>InitServlet</servlet-name>
        <servlet-class>com.minotauro.sandbox.init.simple.InitServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>AppServlet</servlet-name>
        <url-pattern>/app</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>InitServlet</servlet-name>
        <url-pattern>/InitServlet</url-pattern>
    </servlet-mapping>
</web-app>

Noten que lo extra es:

Código:
    <listener>
        <listener-class>com.minotauro.echo.app.SessionTrackerListener</listener-class>
    </listener>

3) Cada vez que necesiten hacer logout de todos los usuarios, incluido el usuario que invoca la operación simplemente tienen que invocar a:

Código:
SessionTrackerListener.getInstance().invalidateAllSessions();

Eso es todo. ¿Fácil verdad? Wink


Esto que viene a continuación si es particular de CLEDA. Realmente no hace falta que lo hagan, es simplemente lo que yo hice para probar que lo anterior funcionaba bien desde CLEDA.


Para probarlo lo que hice fue crear un evento de menu (AppDesktopEvent):

Código:
/*
* Created on 13/07/2012
*/
package com.minotauro.echo.desktop.event;

import com.minotauro.echo.app.SessionTrackerListener;
import com.minotauro.echo.desktop.AppDesktop;
import com.minotauro.echo.desktop.AppDesktopEvent;
import com.minotauro.menu.model.MMenu;

/**
* @author Demián Gutierrez
*/
public class LogoutAllEvent implements AppDesktopEvent {

  @Override
  public void run(AppDesktop desktop, MMenu menu) {
    SessionTrackerListener.getInstance().invalidateAllSessions();
  }
}

Lo añadí al menu (/CledaSandbox/src/main/java/com/minotauro/sandbox/init/simple/menu.xml):

Código:
    <event route="admin/auth/kick" order="0" i18nCls="admin" i18nKey="kick"
        handler="com.minotauro.echo.desktop.event.LogoutAllEvent" priv="main.admin.kick"/>

Añadí el privilegio respectivo y se lo añadí al perfil de administrador (/CledaSandbox/src/main/java/com/minotauro/sandbox/init/simple/priv.xml) y (/CledaSandbox/src/main/java/com/minotauro/sandbox/init/simple/prof.xml):

Código:
    <priv name="main.admin.kick">
        <description>main.admin.kick</description>
    </priv>

Código:
    <prof name="admin">
        <description>admin</description>
        <priv name="main.admin.kick" />
        <priv name="main.admin.user" />
        <priv name="main.admin.prof" />
    </prof>

Luego añadí las claves de I18N extra para los menús en (/CledaSandbox/src/main/java/com/minotauro/sandbox/gui/user/Menu_en.properties), y corrí el _CledaI18N respectivo:

Código:
admin = Admin

kick = Kick All Users
user = Users
prof = Profs

exit = Exit

Luego reinicializan la BD y en el menú de admin deben tener una entrada "Kick All Users" que invalida todas las sesiones. Lo pueden probar con dos navegadores abiertos (ojo, dos instancias distintas de firefox, es decir corran "firefox -P --no-remote") y entren con un admin y otro usuario. Reinicien la sesión desde el admin y traten en cualquier navegador de hacer cualquier cosa. Debería mostrarles una pantalla azul y botarlos al login.

[Imagen: dmi-1.jpg]
13-07-2012 07:53 PM
Visita su sitio web Encuentra todos sus mensajes Cita este mensaje en tu respuesta
JD19 Sin conexión
mata tigres
*

Mensajes: 11
Registro en: Oct 2011
Reputación: 0
Mensaje: #3
RE: Log out
Profesor ha surgido un problema al implementar este metodo.
al agregar el listener al web.xml, el tomcat deja de reconocerlo, no reconoce ningun servlet. el tomcat trabaja pero no cargar ninguna informacion. no se por que se dara este error.
20-09-2012 09:24 PM
Encuentra todos sus mensajes Cita este mensaje en tu respuesta
demian Sin conexión
Administrator
*******

Mensajes: 1.808
Registro en: Jun 2010
Reputación: 0
Mensaje: #4
RE: Log out
Hola Joel,

(20-09-2012 09:24 PM)JD19 escribió:  Profesor ha surgido un problema al implementar este metodo.
al agregar el listener al web.xml, el tomcat deja de reconocerlo, no reconoce ningun servlet. el tomcat trabaja pero no cargar ninguna informacion. no se por que se dara este error.

No se, tendría que encarar el problema frente a la máquina. Revisa (dos veces de ser posible) lo evidente, es decir, nombres de clase, que encuentre la clase, que las dependencias estén ok, que el XML esté ok, etc.


Debe ser una tontería porque yo lo probé bastante y en mi máquina funciona. Cualquier cosa me buscas en la facultad y lo tratamos de arreglar en tu máquina directamente.

Saludos,

[Imagen: dmi-1.jpg]
21-09-2012 12:05 AM
Visita su sitio web Encuentra todos sus mensajes Cita este mensaje en tu respuesta
JD19 Sin conexión
mata tigres
*

Mensajes: 11
Registro en: Oct 2011
Reputación: 0
Mensaje: #5
RE: Log out
(21-09-2012 12:05 AM)demian escribió:  Revisa (dos veces de ser posible) lo evidente, es decir, nombres de clase, que encuentre la clase,
no creo que sea eso. Con eclipse, verifique la direccion como si fuera un hipervinculo(ctrl + click sobre la direccion) y me direciono bien.

(21-09-2012 12:05 AM)demian escribió:  que las dependencias estén ok

no entiendo a que se refiere.

(21-09-2012 12:05 AM)demian escribió:  que el XML esté ok, etc.

lo unico que cambie en el web.xml es agregar:
Código:
    <listener>
        <listener-class>com.minotauro.echo.app.SessionTrackerListener</listener-class>
    </listener>
y al hacer esto deja de reconoce los dos servlets. Nota: agrego esto en las lineas antes de declarar los servlets.[/code]
21-09-2012 04:38 PM
Encuentra todos sus mensajes Cita este mensaje en tu respuesta
demian Sin conexión
Administrator
*******

Mensajes: 1.808
Registro en: Jun 2010
Reputación: 0
Mensaje: #6
RE: Log out
(21-09-2012 04:38 PM)JD19 escribió:  
(21-09-2012 12:05 AM)demian escribió:  que las dependencias estén ok

no entiendo a que se refiere.

A que el proyecto WEB consiga por ejemplo el proyecto donde está la clase del listener, suponiendo que esté en otro proyecto.

Por lo que me cuentas no hay mucho que puedo hacer por esta vía, vas a tener que buscarme en la facultad el lunes para que miremos código en tu máquina y veamos que sucede.

[Imagen: dmi-1.jpg]
21-09-2012 10:31 PM
Visita su sitio web Encuentra todos sus mensajes Cita este mensaje en tu respuesta
demian Sin conexión
Administrator
*******

Mensajes: 1.808
Registro en: Jun 2010
Reputación: 0
Mensaje: #7
RE: Log out (Como seguir la pista e invalidar todos los HttpSession)
Hola Joel,

La solución a tu problema va por aquí:

En com.minotauro.echo.app.BaseAppInstance (CledaEcho) modifica el setUser de la siguiente forma:

Código:
public static final String CLEDA_USERNAME = "cleda.username";

  // ....

  public static void setUser(MUser user) {
    BaseAppInstance baseAppInstance = //
    (BaseAppInstance) BaseAppInstance.getActive();

    baseAppInstance.user = user;

    ContainerContext containerContext = //
    (ContainerContext) baseAppInstance.getContextProperty( //
        ContainerContext.CONTEXT_PROPERTY_NAME);

    if (user != null) {
      baseAppInstance.setLocale(user.getLocale());
      containerContext.getSession().setAttribute( //
          CLEDA_USERNAME, user.getUser());
    } else {
      containerContext.getSession().removeAttribute( //
          CLEDA_USERNAME);
    }
  }

Eso guarda en los atributos de la sesión bajo la clave CLEDA_USERNAME el nombre del usuario.

Luego en com.minotauro.echo.app.SessionTrackerListener (CledaEcho) debes añadir un método:

Código:
public synchronized void invalidateAllSessionsBut(String skipUser) {
    HttpSession[] httpSessionArray = //
    httpSessionSet.toArray(new HttpSession[0]);

    for (HttpSession httpSession : httpSessionArray) {

      String currUser = (String) httpSession.getAttribute( //
          BaseAppInstance.CLEDA_USERNAME);

      if (skipUser.equals(currUser)) {
        continue;
      }

      httpSession.invalidate();
    }
  }

Que invalida todas las sesiones excepto la que corresponde al nombre de usuario pasado como parámetro. Eso resuelve tu problema del "logout" de todos los usuarios menos el "plugin-manager".

Saludos,
Por cierto, es posible que exista una solución más a la "Echo3 way" pero en este momento no tengo los fuentes de Echo3 a mano como para hacer un poquito de ingeniería inversa...

[Imagen: dmi-1.jpg]
27-09-2012 08:46 PM
Visita su sitio web Encuentra todos sus mensajes Cita este mensaje en tu respuesta
Enviar respuesta 


Salto de foro:


Usuario(s) navegando en este tema: 1 invitado(s)