2009-07-17 6 views
11

Ich habe eine Situation, in der ich zwei verschiedene Webapps auf einem einzigen Server mit verschiedenen Ports ausführen kann. Beide verwenden den Jetty-Servlet-Container von Java, sodass beide einen Cookie-Parameter mit dem Namen JSESSIONID verwenden, um die Sitzungs-ID nachzuverfolgen. Diese beiden Webapps kämpfen um die Session-ID.JSESSIONID-Kollision zwischen zwei Servern auf derselben IP-Adresse, aber verschiedenen Ports

  • Öffnen Sie ein Firefox-Registerkarte, und gehen Sie zu WebApp1
  • WebApp1 der HTTP-Antwort hat eine Set-Cookie-Header mit JSESSIONID = 1
  • Firefox hat jetzt einen Cookie-Header mit JSESSIONID = 1 in allem ist es HTTP-Anfragen an WebApp1
  • öffnen Sie einen zweiten Firefox-Registerkarte, und gehen Sie zu webapp2
  • der HTTP-reqeust zu webapp2 hat auch einen Cookie-Header mit JSESSIONID = 1, aber in der doGet, wenn ich req.getSession(false); ich null bekommen nennen. Und wenn ich rufe req.getSession(true) Ich bekomme ein neues Session-Objekt, aber dann hat die HTTP-Antwort von WebApp2 eine Set-Cookie-Header mit JSESSIONID = 20
  • Jetzt hat WebApp2 eine funktionierende Sitzung, aber WebApp1 Sitzung ist weg. Wenn ich zur WebApp1 gehe, bekomme ich eine neue Sitzung, die die Sitzung der WebApp2 wegbläst.
  • Weiter für immer

So sind die Sessions zwischen jedem Web-App Dreschen. Ich würde wirklich gerne für die req.getSession(false) eine gültige Sitzung zurückgeben, wenn bereits ein JSESSIONID-Cookie definiert ist.

Eine Option besteht darin, das Session-Framework mit einer HashMap und Cookies namens WEBAPP1SESSIONID und WEBAPP2SESSIONID grundlegend neu zu implementieren, aber das ist schlecht und bedeutet, dass ich die neuen Sessions in ActionServlet und ein paar andere Orte hacken muss.

Dies muss ein Problem sein, auf das andere gestoßen sind. Ist Jettys HttpServletRequest.getSession(boolean) nur beschissen?

Antwort

2

Ich hatte ein ähnliches Problem: Eine oder mehrere Instanzen der gleichen Anwendung auf localhost auf verschiedenen Ports, zum Startzeitpunkt der Anwendung ausgewählt, jeder mit seiner eigenen Steg-Instanz.

Nach einer Weile ich kam mit dieser:

  • Warten Anlegestelle
  • SocketManager die Nutzung Anlegestelle zu initialisieren, den Hafen zu bekommen (socketManager.getLocalPort())
  • setzen Sie den Cookie-Namen durch den Sessionmanager (sessionHandler.getSessionManager().setSessionCookie(String))

Auf diese Weise habe ich einen Unterschied Cookie-Name für jede Instanz - also keine Interferenz mehr.

0

Es ist korrektes Verhalten. Sie können zwei Ihrer Webapps auf verschiedenen Domänen oder auf verschiedenen Pfaden platzieren.

0

Sie könnten auch den Jsessionid-Cookie-Pfad festlegen, glaube ich.

3

Es ist nicht Jettys Problem, so wurde die Cookie-Spezifikation definiert. Neben dem Name/Wert-Paar kann ein Cookie auch ein Ablaufdatum, einen Pfad, einen Domain-Namen und ob das Cookie sicher ist (d. H. Nur für SSL-Verbindungen bestimmt) enthalten. Die Portnummer ist oben nicht aufgeführt ;-) also muss man entweder den Pfad oder die Domain variieren, wie Stepancheg in seiner Antwort sagt.

+0

Mein Problem ist, dass, wenn Jetty geht eine neue Sitzung, die standardmäßig zu erstellen, ist es nicht einmal versuchen, den vorhandenen Wert von JSESSIONID zu verwenden. Es wählt einfach einen neuen Wert dafür aus. Wenn es bestehende wiederverwendet, dann könnten meine beiden Instanzen von Jetty nett spielen. –

1

Ich habe graben, und ich fand, dass in AbstractSessionManager, gibt es eine Methode namens getCrossContextSessionIDs(). Wenn true zurückgegeben wird, überprüft Jetty beim Erstellen einer neuen Sitzung zunächst, ob JSESSIONID festgelegt ist, und versucht, diese vorhandene Sitzungs-ID zu verwenden. Ich denke, ich kann die Werte auf true mit einer Art von Java-Eigenschaft beim Start festlegen.

Bei weiterem Graben hilft mir das nur, wenn ich zwei Webapps in verschiedenen Kontexten desselben Jetty starte (daher Cross-Context). Beim Erstellen eines neuen Objekts Session wird ein neuer Wert JSESSIONID gewählt. Wenn getCrossContextSessionIDs()true zurückgibt, überprüft es, ob der aktuelle JSESSIONID Wert von diesem Jetty (einschließlich aller anderen Kontexte) erstellt wurde und falls ja, wird er es wiederverwenden.

Da es sich um zwei verschiedene Jetty-Instanzen handelt, die auf zwei verschiedenen Ports ausgeführt werden, muss ich Jettys Quelle hacken, um diese Überprüfung nicht durchzuführen, oder einfach mein eigenes sitzungsähnliches Framework erstellen.

+0

Das klingt, als müssten Sie bei Jetty bleiben - ich nehme nicht an, dass diese Lösung mit anderen Servlet-Containern funktioniert. Hoffe, du musst nie wechseln :-) –

+0

Du hast recht. Wir betrachten die Änderung von Jettys Code als kurzfristige Lösung. Auf lange Sicht werden wir entweder unser eigenes Sitzungsmanagement mithilfe verschiedener Cookies implementieren, oder alles wird sich ändern, wenn wir ein SSO-System implementieren. –

2

In unserem Fall verwenden wir Tomcat, daher besteht die Lösung darin, für jede Instanz verschiedene Session-Cookie-Namen zu verwenden.

In context.xml etwas tun, wie

<Context sessionCookieName="JSessionId_8080"> 
Verwandte Themen