Shiro - 无法使用散列密码进行身份验证

时间:2014-11-03 00:07:48

标签: mysql shiro

我尝试使用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 Hashes,但我对如何继续进行了混淆。

(1)我不想重新发明轮子。 Shiro有没有本能做到这一点?我已经检查了Les'链接到PasswordMatcher和PasswordService(来自链接shiro with jdbc and hashed passwords),但这仍然不清楚。我需要sub-classingPasswordMatcher吗?

(2)架构问题:谁实际调用了doCredentialsMatch(..)方法?它是执行login(...)方法时的领域吗?

(3)doCredentialsMap(...)方法的AuthenticationInfo参数..是由Realm提供的吗?由于Realms封装了实际的安全数据,在我的例子中,这是一个从RDBMS返回密码的SQL查询创建的对象吗?

非常感谢你的时间!我希望能够在我全身心地投入到文档中时为文档做出贡献。

1 个答案:

答案 0 :(得分:1)

第1项: 我怀疑你可能会遇到涉及"盐风格的this issue" JdbcRealm的参数,默认为" NO_SALT"。这会导致哈希工作,但如果您在密码中添加盐,则域将无法正确匹配它们。

以后是您的步骤:

基于COLUMN的salt样式的默认查询如下,"从username =?"的用户中选择密码,password_salt。如果您无法使用该结构,则需要通过您的' shiro.ini提供新的查询。具有相似的结构。

jdbcRealm.authenticationQuery=select password, salt_column_here from users where username = ?

这是related question

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

项目3:是的,该领域将AuthenticationInfo提供给doCredentialsMatch(..)方法。