我们有一个基于Play框架1构建的Web应用程序。当前版本的Play是1.2.7。它在Amazon EC2实例中的Ubuntu 12.04上运行。
最近,我们在测试服务器上遇到了一种特殊且非常令人担忧的行为。只有少数人使用该系统:一些开发人员和一些测试人员。发生了什么事情是一个用户的会话cookie被给了另外两个用户。假设您使用系统有用户A,B和C,每个用户都是自己登录的。突然发生的是,所有这些似乎都以用户A的身份登录,没有任何人做任何特别的事情。
Play正在管理自己的会话cookie。假设会话cookie名称配置为XYZ_SESSION。当我们看到这种行为时,我能够检查用户A和B的会话cookie(C在不同的组织和站点中)。 B所拥有的会话cookie与A的100%相同。在这个应用程序中,会话cookie用于存储用户名,电子邮件地址等。因此在实践中,用户B突然与用户A进行相同的会话。我没有检查用户C的cookie,但是口头报告显示他突然以用户A登录。
这实际上是第二次使用此应用程序观察到此行为。之前的时间是几个月前,然后开发了一个cludgy hack来注意这种情况并注销相关用户。但是,黑客攻击不是很难维护或可扩展,我们想要摆脱它。并且最好找出问题的根本原因。
应用程序的身份验证逻辑是使用OpenID4Java实现的。但是,发生此行为时,所有用户都已登录。
我们对这种行为的可能原因有一个理论。在应用程序中,我们有一个BaseController类,它继承了Play的Controller类,并用作所有控制器的基类。在BaseController中,有一些代码可以获取并放入会话容器。在该类的代码中,会话被称为" session",这意味着Play的Controller类中的静态字段。假设Play的增强器将增强对Scope.Session类中使用ThreadLocal字段的引用。增强将由Play的ControllersEnhancer类完成。但是,在ControllersEnhancer中检查方法enhanceThisClass的代码时,它使用了CtClass / getDeclaredMethods。在该方法的评论中,它表示"未包含继承的方法。"我不完全理解如何调用enhanceThisClass,所以我不完全确定理论是多么可靠。
所以,我们怀疑Play实际上跳过了这个BaseController类中的代码,并且Play的Controller类中的静态会话字段被原样用得很简单,这与线程的合适调度相结合会导致会话重复!
这个问题很难再现,因此我们还没有最终确认这是我们观察到的行为的原因。
有人有任何见解吗?有没有看到与Play相似的行为?能够证明理论是对还是错?
答案 0 :(得分:0)
在我的工作中,我们在很多应用程序中使用play 1.2.7。上个月我们看到了与Play相同的问题。两个用户具有相同的会话。在我们的例子中,应用程序分为两个模块(目录和结帐),目录使用1.2.7和结帐的模块1.2.4。因为模块之间的区别Play!在每个模块中创建相同的会话,并将此会话提供给用户。我不知道你的应用程序是否与我们的结构相同,但如果是,我建议你看看。