前几天,我发生了一件非常奇怪和尴尬的事情,我无法用语言描述发生的事情。
我的应用程序在Tomcat 7上都运行了与JSF 2.1,Hibernate 4,Spring Security集成的Spring3。我正在与C级重要人员通电话,并且我们同时在同一页面上同时处于测试环境中。在他的页面提出我的个人帐户详细信息的几乎同一时间,他转到了我正在浏览的页面。我不相信他,所以我走到他的办公室,果然,他以某种方式登录为我的帐户,但他没有密码。
该应用程序将保护患者的健康信息,因此我被命令向C级提供发生了什么情况的完整报告,但是我找不到这样做的可能性。我搜寻了代码库,却一无所获。我试图多次重现准确的场景,但从未能够重现。我什至没有一个令我满意的有根据的猜测。
我认为也许对存储在Tomcat应用程序上下文实现中的会话进行了一些不安全的线程操作,但是如果它不可复制,则我无法证明这一点。我还认为,由于Spring Security在其他请求之前充当过滤器,并转发其他servlet过滤器之一可能受到干扰。另外两个是我最近添加的Primefaces File Upload过滤器和Omnifaces SEO过滤器。
实际上,Omnifaces过滤器确实干扰了我必须修改其配置的Primefaces File Upload过滤器,因此它们两者之间可以很好地配合使用,因此我仍然觉得这也是可能的。
Spring Security是否存在引起类似问题的已知错误?Tomcat是否存在与意外地从ApplicationContext提供错误的会话状态有关的已知问题?是否有人遇到过类似的问题或对此有独特的见解?
编辑: 发布此消息后不久,我发现了此消息,仅在几天前发布:
会话混合-Apache httpd与mod_jk,tomcat,Spring Security- 提供其他用户的数据
它几乎与我在Tomcat前面有Apache httpd + mod_jk插件的设置完全相同,因此我当然不疯:)
更新:
我能够在开发环境中重现该问题,而无需使用mod_jk或Apache,因此我可以可靠地将其排除在外。
我想到了 :)
这有点像开发人员错误,但这也是Spring的荒谬默认行为。我有一个名为SessionBean的JSF托管Bean,我声明为@SessionScope。当您将JSF和Spring集成在一起时,JSF依赖项注入与Spring依赖项注入发生冲突,因此Spring重写了处理该问题的JSF模块,而只包装了Spring DI。因此,当我将JSF ManagedBean声明为Session Scoped时,我还必须为其添加@Controller注释,以便也将其识别为Spring Bean。
@SessionScope
@Controller
事实证明,Spring不了解JSF @RequestScoped和@SessionScoped注释。Spring有其自己的注释,简称为@Scope(value = "request|session|singleton?|etc...")。
@RequestScoped
@SessionScoped
@Scope(value = "request|session|singleton?|etc...")
由于Spring无法识别我设置的JSF范围,因此将默认创建的Bean作为SINGLETON对待。
因此,每次有人登录时,它都会覆盖我用来缓存从身份验证主体中提取的已登录用户的属性。然后,做任何事情的每个人都以不同的用户身份登录。
spring的美好,顺便 警告 您配置错误的豆子。
感谢大家的帮助,希望这对将来的访问者有所帮助!