当状态保存方法设置为客户端且用户会话有效时,在集群环境中获取ViewExpiredException [英] Getting ViewExpiredException in clustered environment while state saving method is set to client and user session is valid
问题描述
我有一个使用 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.clientStateTimeout
web.xmlweb.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
.
- com.sun.faces.ClientStateSavingPassword - 实际密码的建议?
- javax.faces.application.ViewExpiredException:无法查看恢复
这篇关于当状态保存方法设置为客户端且用户会话有效时,在集群环境中获取ViewExpiredException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!