JBoss EPA 6.4.17集群SSO会话超时后未销毁问题求助
这确实是JBoss EAP 6.x系列中ClusteredSingleSignOn模块的一个已知问题,算是设计上的小疏漏——尤其在集群环境下处理会话超时销毁场景时,容易出现你描述的情况:杀死浏览器进程后,SSO会话没有按maxInactiveInterval设置销毁,导致用户一段时间后仍能自动登录,存在明显安全风险。
问题根源确认
你调试发现的细节完全准确:当会话触发超时事件时,ClusteredSingleSignOn.java的sessionEvent方法仅执行了processExpires()清理已过期会话列表,但没有主动销毁当前关联的SSO会话实例,也没有同步清理集群缓存中的对应条目,最终造成会话泄漏。这个问题在Red Hat官方的问题追踪系统中已有记录,属于特定集群SSO场景下的会话管理缺陷。
可用修复方案
1. 官方补丁修复
Red Hat针对JBoss EAP 6.4.17及后续小版本提供了专门的补丁,修正了ClusteredSingleSignOn中会话超时处理的逻辑:触发超时事件时,会在调用processExpires()的同时,主动调用removeSession()销毁当前关联的SSO会话,并同步清理集群缓存中的相关数据。你可以通过Red Hat官方支持渠道(如客户门户)获取对应补丁,按照补丁说明部署到集群所有节点即可。
2. 临时Workaround(无法获取补丁时)
如果暂时无法获取官方补丁,可以尝试以下几种临时解决方案:
调整缓存淘汰策略:
虽然你已经将maxEmptyLife设为0,但可以配合配置jboss.web.session.caching.eviction_policy为LRU(最近最少使用),并设置合理的max_entries值,让缓存中长时间未访问的SSO会话被主动淘汰。不过这是间接手段,不能完全替代会话的主动销毁。自定义SessionListener手动销毁SSO会话:
编写一个自定义的HttpSessionListener,在会话销毁事件中主动清理关联的SSO会话。示例代码如下:public class CustomSSOSessionCleanupListener implements HttpSessionListener { @Override public void sessionDestroyed(HttpSessionEvent event) { HttpSession session = event.getSession(); // 获取ClusteredSingleSignOn实例 ClusteredSingleSignOn ssoManager = (ClusteredSingleSignOn) session.getServletContext().getAttribute(ClusteredSingleSignOn.class.getName()); if (ssoManager != null) { // 获取当前会话关联的SSO ID String ssoId = (String) session.getAttribute("JSESSIONIDSSO"); if (ssoId != null) { // 主动销毁SSO会话 ssoManager.invalidate(ssoId); } } } }然后在你的web.xml中注册这个监听器:
<listener> <listener-class>com.yourcompany.listeners.CustomSSOSessionCleanupListener</listener-class> </listener>定期清理定时任务:
编写一个定时任务(比如使用Quartz或JBoss自带的定时服务),定期遍历集群中的SSO会话,检查会话最后访问时间,超过maxInactiveInterval则主动调用销毁方法。注意要处理集群环境下的分布式锁,避免重复清理同一会话。
3. 升级到更高版本
如果业务允许,建议直接升级到JBoss EAP 7.x及以上版本。后续版本重新设计了集群SSO的会话管理机制,彻底解决了这个会话泄漏问题,同时还提供了更丰富的SSO配置选项、更好的性能和安全性。
注意事项
- 无论采用哪种方案,都需要重启集群所有节点,确保配置或补丁在整个集群中生效。
- 修复后要全面测试各种场景:手动注销、关闭浏览器标签页、杀死浏览器进程、自然会话超时等,验证SSO会话是否能正常销毁,避免引入新的问题。
内容的提问来源于stack exchange,提问作者nithin rithin

