【发布时间】:2014-10-28 13:57:07
【问题描述】:
我遇到了一个奇怪的 Shiro 问题,我正试图追踪有时(可能是竞争条件)会话最终将身份验证设置包含为 true,但没有主体。
这似乎是正在发生的事情:
- 用户通过 URL 访问我们的系统。
- URL 包含一个神奇的路径,用于对其进行身份验证并将其登录。现在,Subject 已通过身份验证并具有一个 Principal。
- 请求的网页被发送给他们。
- 网页包含其他页面(JavaScript、CSS 等)。第二个请求有时会失败(访问 JavaScript),因为 Subject 现在已经过身份验证,但没有 Principal,因此我们无法对其进行授权。
这是执行登录的代码(第 2 步):
if(!subject.isAuthenticated()) {
// Log the user in
LegacyAuthenticationToken token = new LegacyAuthenticationToken(site, facility, authUrl);
subject.login(token);
}
LegacyJDBCRealm 扩展了 AuthenticatingRealm 并覆盖 doGetAutheticationInfo 以返回一个 SimpleAuthenticationInfo 对象,其中包含主体:
return new SimpleAuthenticationInfo(userKey.toString(), authUrl, getName());
userKey.toString() 是主体。 AuthUrl 是对用户进行身份验证的 URL 提供,而 getName() 是领域的名称。我确实有两个不同的领域在玩——传统和非传统。这会导致问题吗?
通过各种断点,我可以看出第一个主题已正确生成,并且似乎已正确保存到会话中。第二个主题生成不正确,因为会话(相同的会话 ID,我检查过)没有 Principal(即使它的 Authenticated 值为 true)。
我没有任何运气弄清楚是什么代码从会话中删除了 Principal,所以我希望得到一些指示或调试想法。设置断点 SessionDAO.upgdate(Session) 没有被证明有帮助。
【问题讨论】:
-
你确认多个请求使用同一个HttpSession了吗?您可以通过在 AbstractShiroFilter.doFilterInternal 中放置断点来做到这一点
-
您能否详细说明第 2 步是如何完成的。你能确定你的领域正在添加主体吗?
-
dom farr,我已将上面的一些代码添加到我的问题中。我确实有两个领域(旧版和新版)。他们会以某种方式相互干扰吗?来自任何一个的身份验证都被认为是足够的。