JSESSIONID коллизия между двумя серверами на одном и том же ip, но разных портах - PullRequest
11 голосов
/ 18 июля 2009

У меня есть ситуация, когда у меня два разных веб-приложения работают на одном сервере, используя разные порты. Они оба используют Java-контейнер сервлетов Jetty, поэтому они оба используют параметр cookie с именем JSESSIONID для отслеживания идентификатора сеанса. Эти два веб-приложения борются за идентификатор сессии.

  • Откройте вкладку Firefox и перейдите к WebApp1
  • HTTP-ответ WebApp1 имеет заголовок set-cookie с JSESSIONID = 1
  • Firefox теперь имеет заголовок Cookie с JSESSIONID = 1 во всех HTTP-запросах к WebApp1
  • Откройте вторую вкладку Firefox и перейдите к WebApp2
  • Запрос HTTP к WebApp2 также имеет заголовок Cookie с JSESSIONID = 1, но в doGet, когда я вызываю req.getSession(false);, я получаю null. И если я вызываю req.getSession(true), я получаю новый объект Session, но тогда ответ HTTP от WebApp2 имеет заголовок set-cookie с JSESSIONID = 20
  • Теперь в WebApp2 есть рабочий сеанс, но сеанс WebApp1 пропал. Переход к WebApp1 даст мне новую сессию, сорвав сессию WebApp2.
  • Продолжай вечно

Таким образом, сессии срываются между каждым веб-приложением Мне бы очень хотелось, чтобы req.getSession(false) вернул действительный сеанс, если уже определен файл cookie JSESSIONID.

Один из вариантов заключается в том, чтобы в основном переопределить инфраструктуру Session с помощью HashMap и файлов cookie, называемых WEBAPP1SESSIONID и WEBAPP2SESSIONID, но это отстой, и мне придется взламывать новый материал Session в ActionServlet и некоторых других местах.

Это должно быть проблемой, с которой сталкивались другие. Джетти HttpServletRequest.getSession(boolean) просто дерьмо?

Ответы [ 6 ]

3 голосов
/ 23 октября 2015

В нашем случае мы используем Tomcat, поэтому решение состоит в том, чтобы использовать разные имена файлов cookie сеанса в каждом экземпляре.

В context.xml сделать что-то вроде

<Context sessionCookieName="JSessionId_8080">
3 голосов
/ 18 июля 2009

Проблема не в Jetty, а в том, как была определена спецификация cookie. Помимо пары имя / значение файл cookie может также содержать дату истечения срока действия, путь, имя домена и то, является ли файл cookie безопасным (т.е. предназначен только для соединений SSL). Номер порта не указан выше ;-), так что вам нужно будет изменить либо путь, либо домен, как говорит stepancheg в своем ответе.

2 голосов
/ 09 июня 2010

У меня была похожая проблема: один или несколько экземпляров одного и того же приложения на локальном хосте на разных портах, выбранных во время запуска приложения, каждый из которых использует свой собственный экземпляр Jetty.

Через некоторое время я придумал это:

  • Подождите, пока пристань инициализируется
  • используйте SocketManager Jetty для получения порта (socketManager.getLocalPort())
  • установить имя файла cookie через SessionManager (sessionHandler.getSessionManager().setSessionCookie(String))

Таким образом, у меня есть разное имя файла cookie для каждого экземпляра - таким образом, больше нет помех.

1 голос
/ 20 июля 2009

Я копал и обнаружил, что в AbstractSessionManager есть метод, называемый getCrossContextSessionIDs(). Если он возвращает true, то при создании нового сеанса Jetty сначала проверит, задан ли JSESSIONID, и попытается использовать этот существующий идентификатор сеанса. Я думаю, что я могу установить значения true, используя какое-то свойство Java при запуске.

При дальнейшем копании это поможет только в том случае, если я запускаю два веб-приложения в разных контекстах одной и той же Jetty (следовательно, в перекрестном контексте). При создании нового объекта Session выбирается новое значение JSESSIONID. Если getCrossContextSessionIDs() вернет true, то он проверит, было ли текущее значение JSESSIONID создано этой Причалой (включая все другие контексты), и если это так, он будет использовать его повторно.

Поскольку я имею дело с двумя разными экземплярами Jetty, работающими на двух разных портах, мне нужно будет взломать источник Jetty, чтобы не выполнять эту проверку, или просто создать собственную сессионную инфраструктуру.

0 голосов
/ 18 июля 2009

Полагаю, вы также можете указать путь к файлу jsessionid.

0 голосов
/ 18 июля 2009

Это правильное поведение. Вы можете разместить два ваших веб-приложения в разных доменах или по разным путям.

...