Получение ViewExpiredException в кластерной среде, когда для метода сохранения состояния задано значение клиента, а сеанс пользователя действителен

У меня есть приложение JSF, которое использует Mojarra 2.2.9 и развернуто в WebSphere 8.5.5.4 в кластерной среде и javax.faces.STATE_SAVING_METHOD установлен в client,

Несмотря на то, что все мои компоненты приложения находятся в области запросов, иногда, когда пользовательский сеанс действителен, и пользователь выполняет пост-запрос на странице, которую он получает ViewExpiredException, Что может быть причиной этой проблемы и как я могу ее решить? Будет изменение javax.faces.STATE_SAVING_METHOD в server реши это? Если да, то как это влияет на память?

Кроме того, это как-то связано с окружением кластера, и, возможно, в Websphere отсутствует какая-то конфигурация, которая решит проблему?

2 ответа

Решение

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

ОШИБКА: MAC не проверен

Вы должны убедиться, что вы установили jsf/ClientSideStateKey в web.xml с фиксированным ключом AES, в противном случае каждый сервер будет (повторно) генерировать свой собственный ключ AES во время запуска / перезапуска (который используется во время состояния просмотра шифрования).

<env-entry>
    <env-entry-name>jsf/ClientSideSecretKey</env-entry-name>
    <env-entry-type>java.lang.String</env-entry-type>
    <env-entry-value>[AES key in Base64 format]</env-entry-value>
</env-entry>

Вы можете использовать этот фрагмент для генерации случайного AES256 (32-битного) ключа в формате Base64.

KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256); // Use 128 for 16bit key.
String key = Base64.getEncoder().encodeToString(keyGen.generateKey().getEncoded());
System.out.println(key); // Prints AES key in Base64 format.

Если вы получаете Java Security: Неверный размер ключа или параметры по умолчанию? ошибка, установите расширение криптографии, как указано в ссылке, или вместо этого сгенерируйте случайный ключ AES128 (16 бит).

Получив ключ, убедитесь, что вы не публикуете / не открываете ваш ключ.

Далее вы также должны убедиться, что вы добавили <distributable /> тег к web.xml поэтому JSF будет выполнять более агрессивное загрязнение сеансов, а сеансы HTTP (включая сами компоненты bean-объекта view!) правильно синхронизируются между серверами.

Еще одна вероятная причина ViewExpiredException с сохранением состояния на стороне клиента является то, что вы установили параметры контекста Mojarra com.sun.faces.clientStateTimeout в web.xml который представляет время в секундах до того, как состояние входящей клиентской стороны считается истекшим. Это, однако, маловероятно, так как этот контекстный параметр имеет довольно самоочевидное имя, которое вы бы заметили, просто взглянув на web.xml,

Смотрите также:

Вы должны иметь распространяемый тег в вашем файле web.xml, как упомянуто balusc

Другие вопросы по тегам