【问题标题】:Apache Shiro: authenticate with username/password but store user id as the principalApache Shiro:使用用户名/密码进行身份验证,但将用户 ID 存储为主体
【发布时间】:2014-03-24 20:56:33
【问题描述】:

我开始使用 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 存储为主体而不是电子邮件地址,因为这永远不会改变。我将如何实现这一目标?

【问题讨论】:

    标签: java authentication shiro


    【解决方案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(现在是主体)来查找我现在正在查找的用户的详细信息。

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

    【讨论】:

      猜你喜欢
      • 2012-01-20
      • 1970-01-01
      • 1970-01-01
      • 2019-12-17
      • 2021-12-14
      • 2016-11-09
      • 1970-01-01
      • 2012-08-26
      相关资源
      最近更新 更多