Shiro使用主体或会话属性处理用户属性

时间:2017-10-18 11:51:53

标签: session jsf shiro

我在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保持活动状态?

1 个答案:

答案 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从主体复制到了会话中。我不喜欢混淆主要演员表和会话访问权限。这样可以使我的代码保持整洁。