在群集环境中获取ViewExpiredException,同时将状态保存方法设置为客户端并且用户会话有效

时间:2016-01-30 13:57:55

标签: jsf websphere jsf-2.2 websphere-8 viewexpiredexception

我有一个使用Mojarra 2.2.9的JSF应用程序 并在WebSphere 8.5.5.4上部署在集群环境中 并且javax.faces.STATE_SAVING_METHOD设置为client

即使我的所有应用程序bean都是请求作用域,但有时当用户会话有效且用户在页面上执行发布请求时,他会获得ViewExpiredException。可能导致此问题的原因以及如何解决? 将javax.faces.STATE_SAVING_METHOD改为server会解决吗?如果是这样,这对内存的影响是什么?

此外,这是否与群集环境有关,可能在Websphere上有一些缺少配置来解决问题?

2 个答案:

答案 0 :(得分:10)

如果客户端状态由一个服务器加密并由其他服务器解密,并且服务器不使用相同的AES密钥,则会发生这种情况。通常,您还应该在服务器日志中看到以下警告:

  

错误:MAC未验证

您需要确保在jsf/ClientSideStateKey中使用固定的AES密钥设置web.xml,否则每个服务器将在启动/重启期间(重新)生成自己的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>

您可以使用此代码段生成Base64格式的随机AES256(32位)密钥。

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: Illegal key size or default parameters?错误,请按照链接中的说明安装加密扩展,否则生成随机的AES128(16位)密钥。

获得密钥后,请确保不要发布/开源密钥。

此外,您还需要确保已将<distributable />标记添加到web.xml,以便JSF执行更具侵略性的会话变脏,并且HTTP会话(包括视图范围的bean本身!)在服务器之间正确同步。

ViewExpiredException客户端状态保存的另一个可能原因是您在com.sun.faces.clientStateTimeout中设置了特定于Mojarra的上下文参数web.xml,它表示传入客户端之前的时间(以秒为单位)边态被认为已过期。然而,这种情况不太可能,因为上下文参数有一个相当自我解释的名称,你可以通过浏览web.xml来发现它。

另见:

答案 1 :(得分:1)

如balusc

所述,您必须在web.xml中包含distributable标记