Omnifaces CombinedResourceHandler的SHA-384完整性校验异常问题
问题分析
应用闲置一段时间后,浏览器加载Omnifaces合并资源时出现SHA-384校验失败,核心原因是服务器端组合资源的内存缓存被回收(比如WildFly应用钝化、Docker内存限制触发的缓存清理),导致重新生成的资源哈希值与浏览器缓存的integrity属性不匹配,最终资源被浏览器拦截。
解决方案
以下方案按优先级排序,可组合使用:
1. 启用磁盘持久化缓存
Omnifaces默认使用内存缓存组合资源,一旦内存被回收,缓存即丢失。通过配置磁盘缓存,可让组合资源的哈希和内容持久化,避免闲置后缓存失效。
在web.xml中添加如下配置:
<context-param> <param-name>org.omnifaces.COMBINED_RESOURCE_HANDLER_CACHE_DISK_PATH</param-name> <param-value>/opt/wildfly/omnifaces-resource-cache</param-value> <!-- 替换为容器内可读写的持久化路径 --> </context-param>
注意:Docker部署时需确保该路径挂载为持久化卷,或使用容器内不会随重启丢失的路径,同时给WildFly进程配置读写权限。
2. 配置固定版本号
Omnifaces默认自动生成基于时间戳的版本号,缓存失效后重新生成的资源URL版本可能不变,但哈希已改变。改用固定版本号可确保资源内容与哈希的对应关系稳定,浏览器缓存的integrity值始终有效。
在web.xml中添加:
<context-param> <param-name>org.omnifaces.COMBINED_RESOURCE_HANDLER_VERSION</param-name> <param-value>20240520</param-value> <!-- 发布时手动更新版本号,比如用日期或项目版本号 --> </context-param>
3. 调整WildFly缓存/钝化设置
WildFly在应用闲置时可能触发会话钝化或类加载器资源回收,导致Omnifaces内存缓存丢失。可调整WildFly配置文件(standalone.xml/domain.xml):
- 禁用EJB会话钝化:在
<subsystem xmlns="urn:jboss:domain:ejb3:*">下的<session-bean>节点设置passivation-disabled="true" - 延长缓存存活时间:调整
<subsystem xmlns="urn:jboss:domain:web:*">中的缓存配置,确保存活时间长于org.omnifaces.COMBINED_RESOURCE_HANDLER_CACHE_TTL设置的24小时
4. 优化Apache反向代理缓存
确保Apache不会缓存组合资源的响应,避免浏览器获取到旧的integrity值。在Apache配置中添加:
<Location "/javax.faces.resource/omnifaces.combined"> Header set Cache-Control "no-cache, no-store, must-revalidate" Header set Pragma "no-cache" Header set Expires "0" </Location>
5. 临时禁用完整性校验(不推荐)
若以上方案均无法解决,可临时关闭完整性校验,但会失去该机制的安全防护能力:
<context-param> <param-name>org.omnifaces.COMBINED_RESOURCE_HANDLER_INTEGRITY_ENABLED</param-name> <param-value>false</param-value> </context-param>
总结
优先采用磁盘缓存+固定版本号的组合方案,既保留完整性校验的安全特性,又能彻底解决闲置后缓存失效导致的哈希不匹配问题。
内容的提问来源于stack exchange,提问作者Hedhanterz

