Mysql Shiro-无法使用哈希密码进行身份验证

Mysql Shiro-无法使用哈希密码进行身份验证,mysql,shiro,Mysql,Shiro,我正在尝试使用Shiro对我正在构建的JSF Web应用程序进行身份验证和授权。不幸的是,我仍然有一些困难缠绕我的头如何把所有的东西放在一起 我成功地(100%使用shiro.ini文件)将身份验证配置回存储了一组测试凭据的JDBC领域。当凭证以明文形式存储时,它对我非常有效 我的最终目标是统一MySQL数据库中的现有凭证集。密码存储为SHA-256盐哈希。我花了一整天的时间阅读可用的文档(不包括Javadocs),但我仍然难以理解如何准确地设置它 为了分阶段实现,我对我的shiro.ini进行

我正在尝试使用Shiro对我正在构建的JSF Web应用程序进行身份验证和授权。不幸的是,我仍然有一些困难缠绕我的头如何把所有的东西放在一起

我成功地(100%使用shiro.ini文件)将身份验证配置回存储了一组测试凭据的JDBC领域。当凭证以明文形式存储时,它对我非常有效

我的最终目标是统一MySQL数据库中的现有凭证集。密码存储为SHA-256盐哈希。我花了一整天的时间阅读可用的文档(不包括Javadocs),但我仍然难以理解如何准确地设置它

为了分阶段实现,我对我的shiro.ini进行了如下修改,目的是简单地使用SHA-256哈希:

[main]
dataSource = org.apache.shiro.jndi.JndiObjectFactory
dataSource.resourceName = jdbc/Communicator_dev
jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.dataSource = $dataSource
dataSource.resourceRef = true;

jdbcRealm.authenticationQuery = select password from account where site_id = ?
jdbcRealm.userRolesQuery = select user_role from web_roles where site_id = ?

# From https://stackoverflow.com/questions/20742666/shiro-with-jdbc-and-hashed-passwords.
#
passwordService = org.apache.shiro.authc.credential.DefaultPasswordService
#configure the passwordService to use the settings you desire
#...
passwordMatcher = org.apache.shiro.authc.credential.PasswordMatcher
passwordMatcher.passwordService = $passwordService
#...
# Finally, set the matcher on a realm that requires password matching for account authentication:
jdbcRealm.credentialsMatcher = $passwordMatcher
实际的登录逻辑是在页面支持bean中编程的。以下是我当前使用的简单测试源:

    // Create auth token
    UsernamePasswordToken token = new UsernamePasswordToken(this.siteID, this.password);
    // Get the current subject
    Subject currentUser = SecurityUtils.getSubject();
    // Attempt to login
    try {
        currentUser.login(token);
    } catch (AuthenticationException e) {
        System.out.println("Invalid creds.");
        return "";
    }
    return "authenticated.xhtml?faces-redirect=true";
这段代码与存储在我的RDBMS中的明文密码完美结合,但现在我已经对它们进行了哈希运算,它失败了

从我对框架的理解来看,我认为问题在于AuthenticationToken。我知道我需要使用不同的令牌来最终实现存储在RDBMS中的Salted哈希,但我对如何继续感到困惑

(1) 我不想重新发明轮子。Shiro有没有天生就这样做的东西?我已经查看了Les到PasswordMatcher和PasswordService的链接(来自链接),但这仍然不清楚。我需要分类密码匹配器吗

(2) 架构问题:谁真正调用doCredentialsMatch(..)方法?它是执行login(…)方法期间的领域吗

(3) doCredentialsMap(…)方法的AuthenticationInfo参数。。那是由王国提供的吗?由于领域封装了实际的安全数据,在我的例子中,这是从从从RDBMS返回密码的SQL查询创建的对象吗

非常感谢您抽出时间!我希望,当我对这一切了如指掌时,我能够对文档做出贡献。

第1项: 我怀疑您可能会遇到JdbcRealm的“salt样式”参数,该参数默认为“NO_salt”。这会导致散列工作,但如果您在密码中添加了salt,则域将无法正确匹配它们

以下是您的后续步骤:

基于列的salt样式的默认查询如下:“从username=?”的用户中选择password,password\u salt”。如果无法使用该结构,则需要通过具有类似结构的“shiro.ini”提供新查询

jdbcRealm.authenticationQuery=select password, salt_column_here from users where username = ?
这是一本书

第2项:是的,领域调用doCredentialsMatch(..)方法


第3项:是的,领域向doCredentialsMatch(..)方法提供AuthenticationInfo。

仍然很混乱,尽管您的salt样式链接确实有所帮助。一旦salt样式设置为“COLUMN”,如何指定实际包含salt值的列?嗨,Naitouk,我不知道你问了一个后续问题。如果查看示例查询,select子句有两列,“password”和“salt\u column\u here”。第二列是映射数据库salt列的内容,以便Shiro可以找到它。