前几天发生了一件非常奇怪和令人尴尬的事情,我没有言语来描述发生的事情。
我的应用程序在Tomcat 7上运行与JSF 2.1,Hibernate 4,Spring Security集成的Spring 3.我通过电话与C级别的重要人员同时在同一时间在测试环境中相同的页面。当他的页面出现我的个人帐户详细信息时,他开始导航到我正在浏览的页面。我不相信他,所以我走到他的办公室,果然,他不知何故登录了我的帐户,他没有密码。
该应用程序将保护患者健康信息,因此我被命令向C级提供已发生事件的完整报告,但我无法确定这是如何实现的。我搜索了代码库,没有得到什么。我试图在多个场合重现确切的场景,但从未能够重现它。我甚至没有一个受过教育的猜测,我很满意。
我想也许在Tomcat应用程序上下文实现中存储的会话上可能存在一些不安全的线程操作,但如果它不可重现,我无法证明这一点。我还认为,由于Spring Security在其他请求和转发之前作为过滤器运行,可能其中一个servlet过滤器受到干扰。另外两个是我最近添加的Primefaces文件上传过滤器和Omnifaces SEO过滤器。
Omnifaces过滤器实际上干扰了Primefaces文件上传过滤器,我不得不修改它的配置,所以它们中的两个会很好地相互配合,所以我仍然觉得这也许是可能的。
Spring Security是否存在导致类似问题的已知错误? Tomcat是否存在与ApplicationContext意外服务错误会话状态有关的已知问题?是否有其他人遇到过类似的问题或对此有一些独特的见解?
编辑:发布此消息后不久,我发现了这一点,仅在几天前发布:
Session mix up - apache httpd with mod_jk, tomcat, spring security - serving data of other user
这与Tomcat面前的Apache httpd + mod_jk插件几乎完全相同,所以我肯定不会发疯:)
更新
我能够在没有mod_jk或Apache的情况下在我的开发环境中重现这个问题,所以我可以可靠地将其排除在罪魁祸首之外。
答案 0 :(得分:4)
我明白了:)
这有点像开发人员错误,但它也是Spring的一个荒谬的默认行为。
我有一个名为SessionBean的JSF Managed Bean,我声明为@SessionScope
。当您集成JSF和Spring时,JSF依赖注入与Spring依赖注入冲突,因此Spring重写了处理它的JSF模块,而不是将Spring DI包装起来。因此,当我将JSF ManagedBean声明为Session Scoped时,我还必须给它一个@Controller
注释,以便它也被识别为Spring Bean。
事实证明,Spring并不了解JSF @RequestScoped
和@SessionScoped
注释。 Spring有自己的注释,简称为@Scope(value = "request|session|singleton?|etc...")
。
因为Spring没有识别我设置的JSF作用域,所以它将新创建的bean作为缺省值处理为bean,作为SINGLETON。
因此,每当有人登录时,它都会覆盖我用来缓存从Authentication Principal获取的登录用户的属性。然后,所有做过任何事情的人都以不同的用户身份登录。
很好的春天,警告你,你错误配置了该死的豆。
感谢各位的帮助,我希望这对未来的访客有所帮助!