【问题标题】:Shiro Subject Authenticated but missing PrincipalShiro 主题已通过身份验证但缺少主体
【发布时间】:2014-10-28 13:57:07
【问题描述】:

我遇到了一个奇怪的 Shiro 问题,我正试图追踪有时(可能是竞争条件)会话最终将身份验证设置包含为 true,但没有主体。

这似乎是正在发生的事情:

  1. 用户通过 URL 访问我们的系统。
  2. URL 包含一个神奇的路径,用于对其进行身份验证并将其登录。现在,Subject 已通过身份验证并具有一个 Principal。
  3. 请求的网页被发送给他们。
  4. 网页包含其他页面(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,我已将上面的一些代码添加到我的问题中。我确实有两个领域(旧版和新版)。他们会以某种方式相互干扰吗?来自任何一个的身份验证都被认为是足够的。

标签: java shiro


【解决方案1】:

最终,我们将问题归结为一种竞争条件,即我们的 Web 应用程序正在相互广播更改。广播更改的应用程序最终也会读取自己的更改。这并不总是按预期的顺序发生,导致有时会导致我们进入问题中描述的奇怪状态。

我们实施的解决方案是标记每个广播的来源,因此来源会忽略自己的广播。

虽然此解决方案可能对其他人没有直接帮助,但为了完整起见,我将其发布在这里并表明这不是 Shiro 的问题。

【讨论】:

  • 感谢分享!
猜你喜欢
  • 2014-08-28
  • 2015-10-20
  • 1970-01-01
  • 2016-04-02
  • 1970-01-01
  • 2017-10-28
  • 1970-01-01
  • 2014-12-20
  • 2018-07-07
相关资源
最近更新 更多