我在Shiro
应用程序中使用JSF
,并寻找有关如何处理用户属性的指导,例如:Id(来自数据库),电子邮件等,作为信息的一部分。 Shiro Subject
。
阅读Shiro
手册后,在我看来,我没有理由拥有SessionScoped
bean来保存用户信息,因为我已经拥有Subject
。问题是如何最好地存储默认情况下不属于Subject
的用户信息。
我见过一些不同的例子,其中有些人使用Principals
而其他人在当前User
中添加了一个单独的自定义Session
对象,如:
User user = userDAO.findByName(user.getUsername());
subject.getSession().setAttribute("user", user);
抓住 - 例如 - 像这样的用户ID会很优雅:
userId = subject.getUserId();
或发送电子邮件:
email = subject.getEmail();
但我想这不太可能 - 所以我的问题是:这是什么最佳做法?我还想问:为了用户会话的目的,有没有什么好的理由让单独的SessionScoped
bean保持活动状态?
答案 0 :(得分:0)
据我所知,主体是用于标识,身份验证或记住我功能的纯对象。因此,将其他信息放入会话(setAttribute)。
当用户登录时,加载数据并将其放入带有setAttribute的会话中。或者,当用户回来时记得我,请使用委托人识别用户,然后将必要的内容重新加载到会话中。
由您决定要为每个用户在会话中保留多少数据。如果要在服务器上保持较小的内存消耗,则只需存储数据以标识用户(也许它已经在主体中)并在每个功能需要时加载数据即可。这种方法通常会占用更多的CPU和数据库。 如果您没有那么多用户,只需进行会话即可,让您的生活更轻松。
// Do login
Subject currentUser = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(email, password);
currentUser.login(token);
// load attribues
Long uuid = (Long) currentUser.getPrincipal();
Long ucid = // load other ids;
String email = // maybe load email and other stuff
// set attributes
currentUser.getSession().setAttribute("UUID", uuid);
currentUser.getSession().setAttribute("UCID", ucid);
currentUser.getSession().setAttribute("EMAIL", email);
...
// some function
public void doSomething() {
Long ucid = (Long)SecurityUtils.getSubject().getSession().getAttribute("UCID");
// do something
}
在我的示例中,我的主体只是唯一用户ID。这足以识别每个用户。有些用户也是客户,因此我也保存了此ID(每次都为我保存数据库访问权限)。 您还可以保存更多内容,例如电子邮件或任何您需要的东西。
为了方便起见,我将UUID从主体复制到了会话中。我不喜欢混淆主要演员表和会话访问权限。这样可以使我的代码保持整洁。