Shiro主题经过身份验证但缺少校长

时间:2014-09-03 23:03:56

标签: java shiro

我有一个奇怪的Shiro问题我试图追踪有时候(竞争条件,可能)会话最终包含认证设置为真,但没有主体

以下是似乎正在发生的事情:

  1. 用户使用网址访问我们的系统。
  2. 该URL包含一个魔术路径,用于对其进行身份验证并将其记录下来。主题现在已通过身份验证并具有主体。
  3. 请求的网页将发送给他们。
  4. 网页包含其他页面(JavaScript,CSS等)。第二个请求有时会失败(访问JavaScript),因为主题现在已经过身份验证,但没有主体,因此我们无法对其进行授权。
  5. 以下是执行登录的代码(步骤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()是Realm的名称。我确实有两个不同的领域 - 遗产和非遗产。这会导致问题吗?

    通过各种断点,我可以确定第一个主题是正确生成的,并且似乎正确地保存到会话中。第二个主题生成不正确,因为会话(我检查的会话ID相同)没有Principal(即使它的Authenticated值为true)。

    我没有任何运气弄清楚什么代码正在从会话中移除Principal,所以我希望得到一些指示或调试想法。设置一个断点SessionDAO.upgdate(Session)并没有证明是有帮助的。

1 个答案:

答案 0 :(得分:0)

最终,我们将问题追踪到竞争状态,即广播的Web应用程序彼此之间发生了变化。广播变更的应用程序最终也会阅读自己的更改。这并不总是按照预期的顺序发生,导致竞争条件有时使我们陷入问题中描述的奇怪状态。

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

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