2009-07-17 9 views
11

Mam sytuację, w której mam dwa różne aplikacje działające na jednym serwerze, używające różnych portów. Oboje uruchamiają kontener serwletu Java Jetty, więc używają parametru cookie o nazwie JSESSIONID do śledzenia identyfikatora sesji. Te dwie aplikacje internetowe walczą o identyfikator sesji.Kolizja JSESSIONID między dwoma serwerami na tym samym ip ale różnych portach

  • Otwórz zakładkę Firefox i przejdź do WebApp1
  • odpowiedzi HTTP WebApp1 zawiera nagłówek set-ciasteczka z JSESSIONID = 1
  • Firefox ma teraz nagłówek Cookie z JSESSIONID = 1 w sumie to żądania HTTP do WebApp1
  • Otwórz druga zakładka Firefox i przejdź do WebApp2
  • reqeust HTTP WebApp2 posiada również nagłówek Cookie z JSESSIONID = 1, ale w doGet, gdy zgłoszę req.getSession(false); uzyskać null. A jeśli zadzwonię pod numer req.getSession(true) otrzymam nowy obiekt Session, ale wtedy odpowiedź HTTP z WebApp2 ma nagłówek set-cookie z JSESSIONID = 20
  • Teraz WebApp2 ma działającą sesję, ale sesja WebApp1 zniknęła. Przechodzenie do WebApp1 da mi nową sesję, dezorientując sesję WebApp2.
  • trwać wiecznie

Więc Sesje są lanie od każdej aplikacji internetowej. Naprawdę chciałbym, aby req.getSession(false) zwrócił prawidłową sesję, jeśli zdefiniowano już plik cookie JSESSIONID.

Jedną z opcji jest zasadniczo ponowne zaimplementowanie struktury sesji za pomocą HashMap i ciasteczek o nazwie WEBAPP1SESSIONID i WEBAPP2SESSIONID, ale to jest do bani i oznacza, że ​​będę musiał zhakować nowe rzeczy z sesji w ActionServlet i kilka innych miejsc.

To musi być problem, z którym inni się spotkali. Czy Jetty's HttpServletRequest.getSession(boolean) jest po prostu brzydki?

Odpowiedz

2

Miałem podobny problem: Jedno lub więcej wystąpień tej samej aplikacji na localhost na różnych portach, wybranych w czasie uruchamiania aplikacji, z których każdy korzystał z własnej instancji pomostu.

Po chwili wpadłem na to:

  • Czekaj na molo zainicjować
  • wykorzystaniu koniecznie molo w SocketManager dostać się z portu (socketManager.getLocalPort())
  • ustawić nazwę pliku cookie przez SessionManager (sessionHandler.getSessionManager().setSessionCookie(String))

W ten sposób mam nazwę pliku cookie różnicy dla każdej instancji - więc nie ma już żadnej ingerencji.

0

To jest prawidłowe zachowanie. Możesz umieścić dwa swoje aplikacje internetowe w różnych domenach lub według różnych ścieżek.

0

Można również ustawić ścieżkę ciasteczek jsessionid, jak sądzę.

3

To nie jest problem Jetty, tak zdefiniowano specyfikację plików cookie. Oprócz pary nazwa/wartość plik cookie może również zawierać datę wygaśnięcia, ścieżkę, nazwę domeny i to, czy plik cookie jest bezpieczny (tj. Przeznaczony wyłącznie dla połączeń SSL). Numer portu nie jest wymieniony powyżej ;-), więc będziesz musiał zmienić ścieżkę lub domenę, jak mówi Stepancheg w swojej odpowiedzi.

+0

Moim problemem jest to, że kiedy Jetty idzie do tworzenia nowej sesji, domyślnie, to nawet nie starają się wykorzystać istniejącą wartość JSESSIONID. Po prostu wybiera dla niego nową wartość. Jeśli ponownie używał istniejących, wtedy moje dwa egzemplarze Jetty mogłyby grać ładnie. –

1

Kopałem i odkryłem, że w AbstractSessionManager istnieje metoda o nazwie getCrossContextSessionIDs(). Jeśli zwróci true, to podczas tworzenia nowej sesji Jetty najpierw sprawdzi, czy JSESSIONID jest ustawione, i spróbuje użyć istniejącego identyfikatora sesji. Myślę, że mogę ustawić wartości na true przy użyciu pewnego rodzaju właściwości java podczas uruchamiania.

Jeśli chodzi o dalsze kopanie, to tylko mi pomoże, jeśli używam dwóch webappów w różnych kontekstach tego samego Mola (stąd kontekst międzykulturowy). Podczas tworzenia nowego obiektu Session wybierana jest nowa wartość JSESSIONID. Jeśli getCrossContextSessionIDs() zwróci true, to sprawdzi, czy aktualna wartość JSESSIONID została utworzona przez ten Jetty (włączając wszystkie inne konteksty), a jeśli tak, to użyje go ponownie.

Ponieważ mam do czynienia z dwiema różnymi instancjami Jetty działającymi na dwóch różnych portach, muszę zhakować źródło Jetty, aby nie wykonać tego sprawdzenia, lub po prostu stworzyć własną strukturę sesyjną.

+0

To brzmi tak, jakbyś musiał trzymać się Jetty - nie sądzę, żeby to rozwiązanie działało z innymi kontenerami serwletów. Mamy nadzieję, że nigdy nie będziesz musiał się przełączać :-) –

+0

Masz rację. Szukamy modyfikacji kodu Jetty jako poprawki krótkoterminowej. Na dłuższą metę wdrożymy własne zarządzanie sesjami za pomocą różnych plików cookie lub wszystko ulegnie zmianie po wdrożeniu systemu SSO. –

2

W naszym przypadku używamy Tomcat, więc rozwiązaniem jest użycie różnych nazw plików cookie sesji dla każdej instancji.

W context.xml zrobić coś

<Context sessionCookieName="JSessionId_8080"> 
Powiązane problemy