2009-07-17 1 views
11

Ho una situazione in cui ho due diverse webapp in esecuzione su un singolo server, utilizzando porte diverse. Entrambi eseguono il contenitore del servlet Jetty di Java, quindi entrambi utilizzano un parametro cookie denominato JSESSIONID per tenere traccia dell'id di sessione. Queste due webapp stanno combattendo per l'ID della sessione.JSESSIONID collisione tra due server sullo stesso IP ma diverse porte

  • Aprire una scheda di Firefox, e andare a WebApp1
  • risposta HTTP di WebApp1 ha un'intestazione set-cookie con JSESSIONID = 1
  • Firefox ha ora un colpo di testa del biscotto con JSESSIONID = 1 in tutta la sua richieste HTTP a WebApp1
  • Aprire una seconda scheda di Firefox, e andare a WebApp2
  • la reqeust HTTP per WebApp2 ha anche un Cookie con JSESSIONID = 1, ma nel doGet, quando chiamo req.getSession(false); ottengo null. E se chiamo req.getSession(true) ottengo un nuovo oggetto Session, ma la risposta HTTP da WebApp2 ha un'intestazione set-cookie con JSESSIONID = 20
  • Ora, WebApp2 ha una sessione funzionante, ma la sessione di WebApp1 non c'è più. Andare su WebApp1 mi darà una nuova sessione, spazzando via la sessione di WebApp2.
  • continuare per sempre

Così le sessioni sono botte tra ogni applicazione web. Mi piacerebbe molto che lo req.getSession(false) restituisse una sessione valida se esiste già un cookie JSESSIONID definito.

Un'opzione è di reimplementare fondamentalmente il framework Session con una HashMap e cookie chiamati WEBAPP1SESSIONID e WEBAPP2SESSIONID, ma questo fa schifo, e significa che dovrò hackerare il nuovo materiale della sessione in ActionServlet e in altri posti.

Questo deve essere un problema che altri hanno riscontrato. È Jetty's HttpServletRequest.getSession(boolean) solo schifoso?

risposta

2

Ho avuto un problema simile: una o più istanze della stessa applicazione su localhost su porte diverse, scelte all'ora di inizio dell'applicazione, ognuna con la propria istanza di jetty.

Dopo un po ', mi si avvicinò con questo:

  • Attendere pontile per inizializzare
  • SocketManager utilizzo del molo per raggiungere il porto (socketManager.getLocalPort())
  • impostare il nome del cookie attraverso il SessionManager (sessionHandler.getSessionManager().setSessionCookie(String))

In questo modo ho un nome di cookie diverso per ogni istanza, quindi nessuna interferenza.

0

È un comportamento corretto. Puoi posizionare due webapp in diversi domini o per percorsi diversi.

0

Si potrebbe anche impostare il percorso del cookie jsessionid, credo.

3

Non è il problema di Jetty, è il modo in cui è stata definita la specifica del cookie. Oltre alla coppia nome/valore, un cookie può contenere anche una data di scadenza, un percorso, un nome di dominio e se il cookie è sicuro (vale a dire solo per le connessioni SSL). Il numero di porta non è elencato in quanto sopra ;-) quindi dovrai variare il percorso o il dominio, come dice Stepancheg nella sua risposta.

+0

mio problema è che, quando Jetty va a creare una nuova sessione, per impostazione predefinita, non prova nemmeno a utilizzare il valore esistente di JSESSIONID. Si sceglie solo un nuovo valore per questo. Se riutilizzasse quelli esistenti, le mie due istanze di Jetty potrebbero essere belle. –

1

Sto scavando e ho trovato che in AbstractSessionManager, c'è un metodo chiamato getCrossContextSessionIDs(). Se restituisce true, durante la creazione di una nuova sessione, Jetty controlla prima se JSESSIONID è impostato e tenta di utilizzare quell'ID di sessione esistente. Penso di poter impostare i valori su true usando una sorta di proprietà java all'avvio.

Su ulteriori scavi, questo mi aiuterà solo se sto eseguendo due webapps in diversi contesti dello stesso Jetty (quindi, cross-context). Quando si crea un nuovo oggetto Session, viene scelto un nuovo valore JSESSIONID. Se getCrossContextSessionIDs() restituisce true, quindi controllerà se il valore corrente di JSESSIONID è stato creato da questo Jetty (compresi tutti gli altri contesti) e se lo fosse, lo riutilizzerà.

Poiché ho a che fare con due diverse istanze di Jetty in esecuzione su due porte diverse, ho bisogno di hackerare l'origine di Jetty per non eseguire tale controllo, o semplicemente creare il mio framework simile alla sessione.

+0

Sembra che tu debba restare con Jetty - Non credo che la soluzione funzionerà con altri contenitori servlet. Spero che tu non debba mai cambiare :-) –

+0

Hai ragione. Stiamo cercando di modificare il codice di Jetty come una soluzione a breve termine. A lungo termine, implementeremo la nostra gestione delle sessioni utilizzando diversi cookie, o tutto cambierà quando implementeremo un sistema SSO. –

2

Nel nostro caso utilizziamo Tomcat, quindi la soluzione è utilizzare nomi di cookie di sessione diversi per ogni istanza.

In context.xml fare qualcosa di simile

<Context sessionCookieName="JSessionId_8080">