Почему WARS не может поделиться информацией о сеансе?

11

Я видел нескольких разработчиков, которые искали решение для этой проблемы: доступ к информации о сеансе из другой WAR (даже если внутри одного EAR) - вот несколько примеров: Есть ли способ поделиться состоянием сеанса между различными приложениями в tomcat? , Сеанс доступа другого веб-приложения , другие файлы WAR, общие ресурсы , Tomcat: как обмениваться данными между двумя приложениями? , Что делает атрибут crossContext сделать в Tomcat? Включает ли это совместное использование сеанса? и так далее...

Из всего, что я искал, есть некоторые конкретные решения в зависимости от контейнера, но это как-то « противоречит спецификации ». Я также просмотрел спецификацию Java EE, но без удачи нашел ответ.

Некоторые разработчики говорят о связи между веб-приложениями, но я склонен не соглашаться. По какой причине можно хранить WAR внутри одного EAR, если не используется соединение? К EJB, например, можно получить доступ локально (даже если внутри другого EJB JAR в том же EAR).

В частности, одна из моих WAR-ов обрабатывает аутентификацию и авторизацию, и я хотел бы поделиться этой информацией с другими WAR-ами (в том же EAR). Я уже успел обойти подобные проблемы, упаковав WAR-файлы в JAR-файлы и поместив их в отдельный WAR-проект (WEB-INF / lib). Но мне не нравится это решение (оно требует огромных усилий для именования сервлетов и так далее).

И ни одно решение не ответило на первый (и самый важный) вопрос: почему WAR не могут делиться информацией о сеансах?

rvcoutinho
источник
1
Не уверен, почему это было отвергнуто, кроме того, что это может быть лучше подходит для SO.
NateDSaint
3
«В соответствии со спецификацией API сервлета 2.3 менеджер сеансов поддерживает определение масштаба сеанса только веб-модулем. Только сервлеты в одном и том же веб-модуле могут получить доступ к данным, связанным с конкретным сеансом». Это можно увидеть снова в HttpSession - «Информация о сеансе распространяется только на текущее веб-приложение (ServletContext), поэтому информация, хранящаяся в одном контексте, не будет видна непосредственно в другом». - Это противоречит спецификации.
(лучше, текущая ссылка для HttpSession )
@MichaelT, спасибо. Но это все равно не отвечает почему.
rvcoutinho
@NateDSaint Несмотря на то, что этот вопрос связан с конкретными технологиями, я полагал, что это скорее концептуальный вопрос. Затем я решил для программистов.
rvcoutinho

Ответы:

7

Относитесь к EAR как к псевдовиртуальной машине

EAR - это просто набор файлов WAR, которые имеют общую конфигурацию и библиотеки, обычно из JAR. Это позволяет легче управлять набором взаимозависимых сервисов в контейнере приложения. Таким образом, вы можете думать о EAR как о простой форме виртуальной машины после ее развертывания в своем контейнере.

Точно так же, как один процесс на виртуальной машине не может влиять на другой, так же верно и для EAR. Все WAR изолированы для защиты их внутреннего состояния.

Масштабная аутентификация

В общем, веб-приложения должны быть без состояний, чтобы хорошо масштабироваться. Наличие большого количества информации в сеансе является антишаблоном, который предотвращает это. Это приводит к конфликту между природой HTTP без сохранения состояния и необходимостью поддерживать быстрое, настраиваемое взаимодействие с пользователем. Аутентификация является классическим вариантом использования и распространена в болтливых API, которым требуется множество аутентифицированных запросов для предоставления функциональности конечному пользователю.

Единый вход и единый выход требуют тщательной сигнализации для правильной работы (рассмотрите возможность частичного выхода из системы), особенно при горизонтальном масштабировании. Простое совместное использование состояния сеанса почти никогда не является хорошим решением, и лучшим подходом является использование единой точки отсчета для пользовательской информации, к которой имеют доступ все узлы в кластере.

Концентрация на быстром кэшированном доступе к соответствующей информации даст гораздо более масштабируемые результаты, чем какое-либо сложное, хрупкое решение для совместного использования сеансов.

Гэри Роу
источник
Спасибо, @GaryRowe. Это ответ, который я искал. Во всяком случае, не может ли это быть решение для разработчика?
rvcoutinho
Еще один вопрос: вы думаете, JBoss Cache может быть хорошим решением? Вы слышали об Apache Shiro (и его сессионной кластеризации)? Что насчет этого?
rvcoutinho
@rvcoutinho Решает ли разработчик приложения, как управлять процессами в ядре Linux? Это аналогичное формулирование вопроса - да, вы могли бы сделать это, но это будет чрезвычайно сложно и, вероятно, причинит вам больше боли, чем альтернативный путь.
Гари Роу
2
@rvcoutinho Я не использовал Apache Shiro (он же Apache Security), но я думаю, что это было бы хорошим решением проблемы общей безопасности. Обязательно рассмотрите возможность интеграции с OpenID и OAuth2, а не развертывания собственного протокола для достижения того же результата. JBoss Cache по своему собственному признанию в тупике заменяется Infinispan, который выглядит довольно сложным. Возможно, вы захотите взглянуть на сайт приложения Twelve-Factor, чтобы увидеть более простое и масштабируемое решение.
Гэри Роу
2

Мне кажется, что в спецификации JEE EAR отсутствует функциональность - возможность совместного использования веб-сеансов между несколькими веб-архивами, связанными в EAR.

Серверы приложений, такие как Weblogic, имеют не стандартные реализации для этой функции.

Мартейн Вербург
источник
Это было мое мнение до сих пор. Я пытался понять, почему был сделан упомянутый выбор.
rvcoutinho
1

Ну, AFAIKS, нет никакой реальной причины, почему вы хотели бы сделать это. WAR - это автономное веб-приложение с собственными (специфичными для веб-приложения) областями действия (например, областью действия сеанса). Если вам нужно разделить функциональность (код Java, страницы JSP, файлы CSS), между несколькими WAR-файлами у вас есть гораздо более разумный вариант упаковки их в виде файлов JAR и их развертывания на сервере приложений. Пакет WAR - это более сложное упаковочное решение, разработанное для инкапсуляции чего-то отличного от простого «общего кода / функциональности». JAR - это более простой формат AND, разработанный для упаковки и совместного использования кода и функций. Почему вы хотите использовать более сложную и не специально предназначенную для этой упаковки упаковку, чтобы поделиться чем-то, когда у вас уже есть более простой и более подходящий для этого формат пакета.

Дракон Шиван
источник
Я согласен с вами. Но только когда речь идет только об общих ресурсах. Но для приложения единого входа мне нужно было бы поделиться информацией о сеансе (о зарегистрированном пользователе). И я не вижу причин, почему это было бы против спецификации.
rvcoutinho
2
Поскольку область действия сеанса не предназначена для совместного использования текущих пользовательских данных между различными приложениями. И потому что SSO подразумевает нечто большее, чем проверка атрибутов области сеанса. Вы можете создавать и упаковывать код вне вашей войны (и который будет зависеть не от вашей войны, а скорее от войны), который будет обращаться к атрибутам области сеанса, если вы захотите (например, фильтр), но лучшим решением будет IMHO. иметь отдельное фасадное приложение или конфигурацию сервера, которая имеет дело с аутентификацией и предоставляет доступ к другим (развернутым военным) приложениям.
Shivan Dragon
Я бы снова согласился с вами. И все же спецификация JavaEE (с использованием JAAS) хранит пользовательскую информацию как часть HttpSession, которая противоположна этому подходу. Одна из причин, по которой я собирался использовать Shiro (он поддерживает ортогональный сеанс).
rvcoutinho
В любом случае, спасибо за ответ. У меня до сих пор нет окончательного ответа на мой вопрос, но все, что вы сказали, относится к делу. +1
rvcoutinho
@ rvcoutinho хорошо, это мое мнение по этому вопросу, извините, это не было более полезным для вас.
Шиван Дракон
0

Я думаю, что это было сделано специально, чтобы различные веб-приложения случайно не перезаписывали информацию о сеансах друг друга. Это может пригодиться в вашем случае, но в целом вы не хотите, чтобы пользователи вызывали сбой приложения или повышали его привилегии только потому, что они используют два веб-приложения одновременно. Нетрудно обмениваться информацией между веб-приложениями; просто создайте класс со статическим HashMap, используйте GUID в качестве ключей и передавайте их как часть параметра URL или HTTP.

user281377
источник
Спасибо. На самом деле, я говорил не о том, чтобы разделить весь сеанс между каждым приложением, а о конкретной информации о сеансе (как о пользователе), когда это необходимо. Может быть, мне было не ясно. Любые предложения по прояснению?
rvcoutinho