Репликация сеанса с VaadinSession не работает

#java #vaadin #session-variables #vaadin7 #shiro

Вопрос:

У нас есть веб-приложение, которое использует Spring Boot (1.5) с Vaadin (7.7) и использует Apache Shiro (1.4.0) для обеспечения безопасности.

Приложение настроено на использование DefaultWebSessionManager , чтобы позволить Shiro обрабатывать управление сеансом вместо контейнера сервлета.

Мы используем официальную интеграцию Vaadin Spring (1.2.0), и после некоторой настройки все работает так, как задумано. VaadinSession Содержит ShiroHttpSession внутреннюю оболочку.

Мы хотим добиться репликации сеанса, настроив Shiro на использование a SessionDAO , который поддерживается внешним Cache , что означает, что сеансы будут (де) сериализованы.

Как только мы начнем использовать это SessionDAO , Vaadin завершит работу и перестанет работать. При замене внешнего кэша на встроенный в память Map для отладки он снова работает.

Кажется, это вызвано тем SpringVaadinServlet , что он сохраняет атрибут VaadinSession as a session . VaadinSession есть Serializable и Javadoc показывает:

Все внутри VaadinSession должно быть сериализуемым, чтобы обеспечить совместимость со схемами, использующими сериализацию для сохранения данных сеанса.

Внутри VaadinSession находятся некоторые поля, которых нет Serializable , например, a Lock , и завернутый http-сеанс внутри также помечен как переходный.

Из-за этого сеанс, который использует Vaadin, будет прерван, как только он будет распространен, что приведет к множеству сбоев.

Получается VaadinSession , что на самом деле не используется при репликации сеанса? Почему это так и как мы можем обойти это?

Примечание: у нас также есть версия приложения, использующая Vaadin 8, и здесь происходит то же самое. Похоже, что проблема вызвана интеграцией Vaadin Spring.

Комментарии:

1. На эту тему есть статья: vaadin.com/blog/session-replication-in-the-world-of-vaadin

2. Привет, Анна, пожалуйста, обновите Apache Shiro как можно быстрее. У нас было несколько уязвимостей, которые вы, возможно, захотите исправить! shiro.apache.org/security-reports.html — Бен

Ответ №1:

Внутри VaadinSession есть некоторые поля, которые не являются сериализуемыми, например, Блокировка, и заключенный в оболочку http-сеанс внутри также помечен как временный.

Завернутый http-сеанс не является частью сеанса Vaadin, это http-сеанс. Таким образом, это временное явление. То же самое можно сказать и о блокировке, экземпляр которой хранится в сеансе http.

Чтобы правильно реализовать сериализацию сеанса, вам необходимо подключаться к событиям сериализации и обновлять переходные процессы при десериализации сеанса. VaadinSession должен быть загружен с VaadinService#loadSession помощью, который вызывает VaadinSession#refreshTransients .

Все внутри VaadinSession должно быть сериализуемым, чтобы обеспечить совместимость со схемами, использующими сериализацию для сохранения данных сеанса.

Это утверждение не означает, что вы можете сериализовать свое приложение «из коробки». Это просто означает, что в случае, если ваше приложение также сериализуемо, при тщательном проектировании вы можете сериализовать все это.

Например, Vaadin не обновляет атрибут сеанса в каждом возможном случае по соображениям производительности. VaadinService#storeSession Для этого есть метод. Поэтому вам нужно либо переопределить правильный метод, либо настроить фильтр запросов. Например, вы могли бы сделать это по адресу VaadinService#endRequest .

Обратите внимание, вам нужно использовать липкие сеансы, чтобы заставить это работать с умеренными усилиями. Если ваш сеанс де-сериализован на другом компьютере, экземпляры блокировки повторного входа не будут действительными. Если вы хотите иметь возможность де-сериализовать сеанс на другом компьютере, для этого потребуется, чтобы ваша инфраструктура могла предлагать распределенную блокировку, которую вы можете использовать вместо блокировки повторного входа в Java, и переопределять Vaadin getSessionLock и setSessionLock методы для ее использования.

Ценные источники дополнительной информации:

Общие замечания от технического директора Vaadin

https://vaadin.com/blog/session-replication-in-the-world-of-vaadin

Отзыв разработчика, который сделал это с одним стеком

https://vaadin.com/learn/tutorials/hazelcast

Мысли другого старшего разработчика

https://mvysny.github.io/vaadin-14-session-replication/