当状态保存方法设置为客户端且用户会话有效时,在集群环境中获取ViewExpiredException [英] Getting ViewExpiredException in clustered environment while state saving method is set to client and user session is valid

查看:22
本文介绍了当状态保存方法设置为客户端且用户会话有效时,在集群环境中获取ViewExpiredException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a JSF application that uses Mojarra 2.2.9 and is deployed on WebSphere 8.5.5.4 on clustered environement and javax.faces.STATE_SAVING_METHOD is set to client.

即使我的所有应用程序 bean 都是请求范围的,但有时当用户会话有效并且用户在页面上执行发布请求时,他会收到 ViewExpiredException.什么可能导致此问题,我该如何解决?将 javax.faces.STATE_SAVING_METHOD 更改为 server 会解决吗?如果是这样,这样做对内存有什么影响?

Even though all my application beans are request scoped, sometimes when the user session is valid and the user is doing post request on a page he gets ViewExpiredException. What may be causing this issue and how can I solve it? Will changing the javax.faces.STATE_SAVING_METHOD to server solve it? If so, what is the impact of doing this on memory?

另外,这是否与集群环境有关,也许 Websphere 上缺少一些可以解决问题的配置?

Also, does this have anything to do with cluster environement and maybe there's some missing configuration on the Websphere that will solve the issue?

推荐答案

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

This will happen if the client side state is encrypted by one server and decrypted by other server and the servers don't use the same AES key for this. Normally, you should also have seen below warning in server log:

错误:MAC 未验证

你需要确保你已经在web.xml中设置了jsf/ClientSideSecretKey 一个固定的AES密钥,否则每个服务器都会(重新)生成自己的AES密钥在启动/重启期间(在加密视图状态期间使用).

You need to ensure that you have set jsf/ClientSideSecretKey in web.xml with a fixed AES key, otherwise each server will (re)generate its own AES key during startup/restart (which is used during encrypting view state).

<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 位)密钥.

You can use this snippet to generate a random AES256 (32bit) key in Base64 format.

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 安全性:非法密钥大小或默认参数? 错误,请按照链接中的说明安装加密扩展,或者生成一个随机的 AES128(16 位)密钥.

In case you get Java Security: Illegal key size or default parameters? error, install the cryptography extension as instructed in the link, or else generate a random AES128 (16bit) key instead.

获得密钥后,请务必确保不要发布/开源您的密钥.

After having the key, make absolutely sure you don't publish/opensource your key.

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

Further you also need to ensure you have added <distributable /> tag to web.xml so JSF will perform more agressive session dirtying and the HTTP sessions (including view scoped beans themselves!) are properly synced across servers.

带有客户端状态保存的 ViewExpiredException 的另一个可能原因是您在 中设置了 Mojarra 特定的上下文参数 com.sun.faces.clientStateTimeoutweb.xml 表示传入客户端状态被视为过期之前的时间(以秒为单位).然而,这里不太可能出现这种情况,因为该上下文参数有一个相当不言自明的名称,您只需扫一眼 web.xml 就会发现.

Another probable cause of ViewExpiredException with client side state saving is that you've set the Mojarra-specific context param com.sun.faces.clientStateTimeout in web.xml which represents the time in seconds before an incoming client side state is considered expired. This is however unlikely the case here as that context param has a rather self-explaining name which you would have spotted by just glancing over web.xml.

这篇关于当状态保存方法设置为客户端且用户会话有效时,在集群环境中获取ViewExpiredException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆