JSESSIONID столкновение между двумя серверами на одном и том же IP-адресе, но с разными портами

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

  • Откройте вкладку Firefox и перейдите в WebApp1
  • HTTP-ответ WebApp1 имеет заголовок set-cookie с JSESSIONID = 1
  • В Firefox теперь есть заголовок Cookie с JSESSIONID = 1 во всех его HTTP-запросах к WebApp1
  • Откройте вторую вкладку Firefox и перейдите в WebApp2
  • HTTP reqeust для 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.

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

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

Ответ 1

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

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

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

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

Ответ 2

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

Ответ 3

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

В context.xml сделайте что-нибудь вроде

<Context sessionCookieName="JSessionId_8080">

Ответ 4

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

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

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

Ответ 5

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

Ответ 6

Вы также можете установить путь jsessionid cookie, я полагаю.