У меня есть стек flex / LCDS, и я обнаружил, что после выхода из системы я часто (но не всегда) начинаю получать Duplicate HTTP Session
ошибки на клиенте.
Вот важные факты о стеке:
- Гибкий клиент имеет функцию входа / выхода в приложении. Страница не обновляется после выхода из системы. (Таким образом, приложение Flex и нижележащий
mx.messaging.FlexClient
остаются инициализированными) - У пользователя может быть открыто несколько вкладок.
per-client-authentication
установлен наfalse
- мы пытаемся достичь SSO (интеграция с CAS), поэтому принцип пользователя привязан к JSession.- Проблема наиболее очевидна при использовании длительного опроса для обмена сообщениями и когда открыты две (или более) вкладки.
- Проблему очень сложно воспроизвести при использовании RTMP или потоковых каналов.
- Пользователь привязан к JSession - то есть, если он входит в систему на Tab1, он попадает в систему на Tab2.
- Когда пользователь выходит из системы с любой вкладки, Jsession становится недействительным.
Вот моя текущая теория относительно того, что вызывает проблему:
- Tab1 (T1) Запускает клиента -> Выпущенный ClientId1 (C1) -> JSession1 (J1) создан
- Tab2 (T2) запускает клиента -> выдан ClientId2 (C2) -> присоединяется к J1
- T1 входит в систему -> J1 Unaffected
- T2 входит в систему -> J1 Unaffected
- T1 и T2 Оба подписываются, начинают опрос более
amflongpolling
- T1 отправляет выход -> J1 недействителен -> J2 создан
- T2 отправляет опрос (против J1)
- Выход из системы T1 завершен, возвращается с J2, файл cookie обновляется
Последние два вызова создают конфликт, при котором LCDS видит, что FlexClient
связан с двумя JSession.
В результате получена ошибка следующего вида:
Server.Processing.DuplicateSessionDetected Обнаружены повторяющиеся HTTP-сеансы FlexSessions, как правило, из-за отключения cookie сеанса удаленным узлом. Сессионные куки-файлы должны быть включены для правильного управления клиентским подключением.
Примечание. Мне удалось воссоздать проблему в отдельном проекте. Я считаю, что проблема не в конкретном коде нашего приложения, а в том, что она вызвана характером состояния / сеанса и конфликтами между несколькими вкладками. разделяя одну и ту же сессию.
Таким образом, я считаю, что проблема вызвана тем, что сеанс недействителен на сервере в результате вызовов с одной вкладки, но до того, как ответ будет отправлен в браузер, чтобы сообщить ему о новом сеансе JSession, вызовы выполняются под старым Jsession .
Каковы некоторые подходящие стратегии защиты от этой проблемы с дублированием сеанса?
Обновлять
Чтобы уточнить, пока сценарий аналогичен рассмотренным здесь есть тонкие различия, которые делают решения в этой статье неуместными.
В частности, в статье обсуждается предотвращение дублирования сеансов путем управления начальным созданием сеансов JSessions в обоих браузерах, с помощью JSP или управляемого вызова RemoteObject.
Flex фактически помогает в этом процессе, предотвращая исходящие вызовы RemoteObject до тех пор, пока не будет определена локальная переменная FlexClient DSid
, показывающая, что начальный сеанс установлен.
Мой сценарий отличается, потому что JSession (и связанные объекты LCDS FlexSession / Client-Side FlexClient) уже были установлены один раз (с использованием методов, обсуждаемых в этой статье) и впоследствии аннулированы через выход из системы, что вызывает session.invalidate()
, уничтожая JSession.
Проблема возникает, когда Tab2 отправляет вызов с устаревшим JSession, дублируя ошибку HTTP-сеанса. Ситуация затем усугубляется, поскольку, когда LCDS выдает ошибку DuplicateHTTPSession, это также делает недействительными все известные Jsessions, прикрепленные к клиенту, а это означает, что Tab1 - что было нормально - теперь имеет устаревший JSession. В следующий раз, когда Tab1 отправит вызов, ИТ-специалист вызывает ошибку DuplicateHTTPSession, и цикл повторяется.
К сожалению, перехватчики фреймворка Flex для задержки вызовов во время установления сеансов не имеют простого способа (который я обнаружил) повторно активировать после установки. (Я пробовал следующее, но безрезультатно :)
// Reset DSid to get a new FlexSession established on LCDS
use namespace mx_internal
public function resetFlexSession()
{
FlexClient.getInstance().id = null;
// Note - using FlexClient.NULL_ID also doesn't work.
}