2009-07-17 16 views
11

Tengo una situación en la que tengo dos webapps diferentes ejecutándose en un solo servidor, usando diferentes puertos. Ambos ejecutan el contenedor de servlets Jetty de Java, por lo que ambos usan un parámetro de cookie llamado JSESSIONID para rastrear la identificación de la sesión. Estas dos webapps están peleando por la identificación de la sesión.Colisión de JSESSIONID entre dos servidores en la misma ip pero puertos diferentes

  • Abrir una pestaña de Firefox, e ir a WebApp1
  • respuesta HTTP de WebApp1 tiene una cabecera de set-galleta con JSESSIONID = 1
  • Firefox ahora tiene una cabecera Cookie con JSESSIONID en todo = 1 es peticiones HTTP a WebApp1
  • abierto una segunda pestaña de Firefox, e ir a webapp2
  • el reqeust HTTP para webapp2 también tiene una cabecera Cookie con JSESSIONID = 1, pero en el doGet, cuando llamo req.getSession(false); consigo null. Y si llamo al req.getSession(true) obtengo un nuevo objeto Session, pero luego la respuesta HTTP de WebApp2 tiene un encabezado set-cookie con JSESSIONID = 20
  • Ahora, WebApp2 tiene una sesión de trabajo, pero la sesión de WebApp1 se ha ido. Ir a WebApp1 me dará una nueva sesión, eliminando la sesión de WebApp2.
  • continuar para siempre

Así que las sesiones se THRASHING entre cada aplicación web. Realmente me gustaría que req.getSession(false) devuelva una sesión válida si ya se ha definido una cookie JSESSIONID.

Una opción es básicamente reimplementar el marco de sesión con un HashMap y las cookies llamadas WEBAPP1SESSIONID y WEBAPP2SESSIONID, pero eso apesta, y significa que tendré que hackear el nuevo material de sesión en ActionServlet y en algunos otros lugares.

Esto debe ser un problema que otros han encontrado. ¿Jetty's HttpServletRequest.getSession(boolean) es horrible?

Respuesta

2

Tuve un problema similar: una o más instancias de la misma aplicación en localhost en diferentes puertos, elegidas al inicio de la aplicación, cada una usando su propia instancia de embarcadero.

Después de un rato, se me ocurrió esto:

  • Espere embarcadero para inicializar
  • SocketManager uso de embarcadero para llegar al puerto (socketManager.getLocalPort())
  • establecer el nombre de la cookie a través de la SessionManager (sessionHandler.getSessionManager().setSessionCookie(String))

De esta manera tengo un nombre de cookie diferente para cada instancia, por lo que ya no interfiere.

0

Es comportamiento correcto. Puedes colocar dos tus webapps en diferentes dominios o por diferentes caminos.

0

También podría establecer la ruta de la cookie jsessionid, creo.

3

No es problema de Jetty, sino cómo se definió la especificación de cookies. Además del par nombre/valor, una cookie también puede contener una fecha de vencimiento, una ruta, un nombre de dominio y si la cookie es segura (es decir, solo para conexiones SSL). El número de puerto no figura en la lista anterior ;-), por lo que deberá variar la ruta o el dominio, como stepancheg dice en su respuesta.

+0

Mi problema es que, cuando embarcadero va a crear una nueva sesión, por defecto, no siquiera trató de utilizar el valor actual de JSESSIONID. Simplemente elige un nuevo valor para ello. Si reutiliza los existentes, mis dos instancias de Jetty podrían ser agradables. –

1

He estado cavando, y encontré que en AbstractSessionManager, hay un método llamado getCrossContextSessionIDs(). Si devuelve true, al crear una nueva sesión, Jetty primero comprobará si JSESSIONID está configurado e intentará usar esa identificación de sesión existente. Creo que puedo establecer los valores en true usando algún tipo de propiedad java al inicio.

En otras excavaciones, esto solo me ayudará si estoy ejecutando dos aplicaciones web en diferentes contextos del mismo Jetty (por lo tanto, contexto cruzado). Al crear un nuevo objeto Session, se elige un nuevo valor JSESSIONID. Si getCrossContextSessionIDs() devuelve true, comprobará si el valor JSESSIONID actual fue creado por este Jetty (incluidos todos los demás contextos) y, en caso afirmativo, lo reutilizará.

Como estoy tratando con dos instancias de Jetty diferentes que se ejecutan en dos puertos diferentes, tendré que piratear la fuente de Jetty para no hacer esa comprobación, o simplemente crear mi propio marco de sesión.

+0

Parece que tendrá que seguir con Jetty; no creo que esa solución funcione con otros contenedores de servlets. Aquí está la esperanza de que nunca tengas que cambiar :-) –

+0

Tienes razón. Estamos buscando modificar el código de Jetty como una solución a corto plazo. A largo plazo, implementaremos nuestra propia administración de sesiones usando diferentes cookies, o todo cambiará cuando implementemos un sistema SSO. –

2

En nuestro caso, estamos utilizando Tomcat, por lo que la solución es utilizar diferentes nombres de cookies de sesión en cada instancia.

En context.xml hacer algo como

<Context sessionCookieName="JSessionId_8080"> 
Cuestiones relacionadas