如何在 Shiro 中更新已验证主题的主体

Posted

技术标签:

【中文标题】如何在 Shiro 中更新已验证主题的主体【英文标题】:How to update principal of an authenticated subject in Shiro 【发布时间】:2015-10-20 12:43:56 【问题描述】:

我在 JSF2 项目中使用 Shiro 1.2.3。我找不到在没有注销的情况下更新已验证主题的主体的方法。当登录用户想要更新他/她的个人资料信息时,我需要这个。我将userBean 存储为主体,它应该与配置文件信息一起更新。以编程方式登录可能是一种解决方案,但这次需要用户的密码才能创建令牌。

【问题讨论】:

为什么要更改用户主体。它是用于他在登录后被允许的所有授权和身份验证的密钥。通常 Principal 是用户的用户 ID。如果您在两者之间进行更改,则可能会显示不一致的行为。此外,根据标准主体是一个用户 ID,不应更改,以便您可以在历史数据中跟踪它。如果您需要更改某些内容,则可能是用户的物理名称。 @dev 您可以将任何对象设置为主体(甚至多个)。然而,在性能方面,建议只存储一个唯一的 id。在我的应用程序中,我将一个轻量级 User 类(具有 userId、username、email、firstname 和 lastname 属性)设置为主体,因为我经常使用 <shiro:principal/> 标签显示每个字段。 【参考方案1】:

已经过去了一段时间,但我希望这对其他人也有用。

当您使用 Shiro 登录时,会创建一个会话并将一个令牌发送到客户端以供进一步请求。

对于每个请求 Shiro 拦截 HTTP 请求,验证令牌是否有效,然后使用 org.apache.shiro.web.mgt.DefaultWebSubjectFactory.createSubject(SubjectContext context) 方法创建一个新主题包含重要的一行

PrincipalCollection principals = wsc.resolvePrincipals();

最终将我们带到包含关键行的解决方法 org.apache.shiro.subject.support.DefaultSubjectContext.resolvePrincipals()

Session session = resolveSession();
if (session != null) 
    principals = (PrincipalCollection) session.getAttribute(PRINCIPALS_SESSION_KEY);

即在不注销的情况下更新您的主题的主体,您需要更新他/她的会话的 PRINCIPALS_SESSION_KEY 属性。总结你的代码可以很简单

PrincipalCollection pc = (PrincipalCollection) getSubject().getSession().getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY;
// do something in here   
getSubject().getSession().setAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY, pc);

【讨论】:

以上是关于如何在 Shiro 中更新已验证主题的主体的主要内容,如果未能解决你的问题,请参考以下文章

Shiro 学习笔记——shiro身份验证

Shiro-身份验证

Shiro身份验证

shiro身份验证

Shiro学习之身份验证

Shiro学习身份验证