Java ApacheShiro:使用用户名/密码进行身份验证,但将用户id存储为主体

Java ApacheShiro:使用用户名/密码进行身份验证,但将用户id存储为主体,java,authentication,shiro,Java,Authentication,Shiro,我开始学习ApacheShiro。我从简单的例子开始,并且随着时间的推移不断增加复杂性 目前,我正在使用JSF从登录表单收集电子邮件地址和密码,并使用UsernamePasswordToken向Shiro验证用户 UsernamePasswordToken token = new UsernamePasswordToken(email, password); SecurityUtils.getSubject().login(token); 通过一个简单的查询,JDBC领域提供了现成的支持 jd

我开始学习ApacheShiro。我从简单的例子开始,并且随着时间的推移不断增加复杂性

目前,我正在使用JSF从登录表单收集电子邮件地址和密码,并使用UsernamePasswordToken向Shiro验证用户

UsernamePasswordToken token = new UsernamePasswordToken(email, password);
SecurityUtils.getSubject().login(token);
通过一个简单的查询,JDBC领域提供了现成的支持

jdbcRealm.authenticationQuery = SELECT password FROM user WHERE email = ?
为了获得有关用户的更多详细信息,例如他们的姓名,我正在由负责人在数据库中查找该用户,这是他们的电子邮件地址

currentUser = userDAO.findByEmail((String) SecurityUtils.getSubject().getPrincipal());

这很有效,但允许用户更改其电子邮件地址,这将中断查找。我的目标是将唯一的用户id存储为主体,而不是电子邮件地址,因为这永远不会更改。如何实现这一点?

我最终用一种简单的方法解决了这个问题-在创建身份验证令牌之前将电子邮件地址转换为用户id,并将用户id用作令牌中的主体

try{
    // Lookup the user by email
    User user = userDAO.findByEmail(email);

    // If no match we can't authenticate
    if(user == null){
        throw new AuthenticationException();
    }

    // Else, build a token with the user id and password
    UsernamePasswordToken token = new UsernamePasswordToken(user.getUserId().toString(), password);

    // Attempt to login
    SecurityUtils.getSubject().login(token);

}catch(AuthenticationException ex){
    return false;
}
我的userdaobean配置为处理javax.persistence.NoResultException并返回null

在我的shiro.ini文件中,我将
jdbcRealm.authenticationQuery
更改为以下内容(注意,我使用的是MySQL)

最后,为了查找关于用户的详细信息,我现在通过用户id查找,用户id现在是主体

currentUser = userDAO.findByUserId(Integer.parseInt((String) SecurityUtils.getSubject().getPrincipal()));
currentUser = userDAO.findByUserId(Integer.parseInt((String) SecurityUtils.getSubject().getPrincipal()));