我开始使用Apache Shiro。我从简单的例子开始,并且在我去的时候一直在增加复杂性。
目前,我正在使用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存储为主体而不是电子邮件地址,因为这永远不会改变。我将如何实现这一目标?
答案 0 :(得分:1)
我最终用一种简单的方法解决了这个问题 - 在创建身份验证令牌之前从电子邮件地址转换为用户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;
}
我的UserDAO bean配置为处理javax.persistence.NoResultException并返回null。
在我的shiro.ini文件中,我已将jdbcRealm.authenticationQuery
更改为以下内容(注意我使用的是MySQL)
jdbcRealm.authenticationQuery = SELECT password FROM user WHERE user_id = CAST(? AS UNSIGNED)
最后,要查找有关用户的详细信息,我现在通过用户ID查找,现在是用户ID。
currentUser = userDAO.findByUserId(Integer.parseInt((String) SecurityUtils.getSubject().getPrincipal()));