如何在 Shiro 中使用 JdbcRealm 对提交的密码进行哈希处理?

Posted

技术标签:

【中文标题】如何在 Shiro 中使用 JdbcRealm 对提交的密码进行哈希处理?【英文标题】:How to Hash Submitted passwords using JdbcRealm in Shiro? 【发布时间】:2015-07-24 10:47:42 【问题描述】:

我创建了一个应用程序并一直在使用 Shiro 进行身份验证。 我遵循了大多数指南以及此处发布的一些关于 shiro 和 Jdbc Realm 的问题。

这是我的 shiro.ini 文件:

[main]
authc.loginUrl=/jsp/loginForm.jsp
authc.successUrl=/test/successUrl.jsp
authc.rememberMeParam = login-remember-me
logout.redirectUrl=/index.jsp

hashService = org.apache.shiro.crypto.hash.DefaultHashService
hashService.hashIterations = 500000
hashService.hashAlgorithmName = SHA-256
hashService.generatePublicSalt = true

hashService.privateSalt = someBase64EncodedSaltValue

realm = org.apache.shiro.realm.jdbc.JdbcRealm
realm.permissionsLookupEnabled = false
realm.authenticationQuery = SELECT password FROM userTable WHERE username = ?

ps = org.apache.shiro.authc.credential.DefaultPasswordService
ps.hashService = $hashService
pm = org.apache.shiro.authc.credential.PasswordMatcher
pm.passwordService = $ps

jof = org.apache.shiro.jndi.JndiObjectFactory
jof.resourceName = java:comp/env/jdbc/theResourceName
jof.requiredType = javax.sql.DataSource
jof.resourceRef = true

realm.dataSource = $jof
realm.credentialsMatcher = $pm

securityManager.realms = $realm

我在 Java 中使用以下代码将密码保存在数据库中:

DefaultHashService hashService = new DefaultHashService();
hashService.setHashIterations(500000);
hashService.setHashAlgorithmName(Sha256Hash.ALGORITHM_NAME);
hashService.setPrivateSalt(new SimpleByteSource(
    "someBase64EncodedSaltValue")); // Same salt as in shiro.ini, but NOT
                                      // base64-encoded.
hashService.setGeneratePublicSalt(true);

DefaultPasswordService pwService = new DefaultPasswordService();
pwService.setHashService(hashService);
this.password = pwService.encryptPassword(password);

一切看起来都很好,并且按预期保存,但问题是我登录时。我已经跟踪到 JdbcRealm.class 的执行,我已经看到比较的值是“原始字符串密码”和加密数据库中的密码。

我是否错过了任何配置步骤?

【问题讨论】:

【参考方案1】:

要使用 Salted,最好为每个用户设置单独的盐。所以将该盐存储在数据库中。 SEE

现在, 扩展org.apache.shiro.realm.jdbc.JdbcRealm 喜欢:

package common.shiro;

import org.apache.shiro.realm.jdbc.JdbcRealm;

public class JDBCSaltedRealm extends JdbcRealm  

    public JDBCSaltedRealm() 
        setSaltStyle(SaltStyle.COLUMN);
    

在 shiro.ini 中:

credentialsMatcher = org.apache.shiro.authc.credential.HashedCredentialsMatcher
credentialsMatcher.hashAlgorithmName=SHA-256
credentialsMatcher.storedCredentialsHexEncoded = false
credentialsMatcher.hashIterations = 500000
credentialsMatcher.hashSalted = true

realm = common.shiro.JDBCSaltedRealm

realm .permissionsLookupEnabled = true
realm .authenticationQuery  = SELECT password,salt  FROM userTable WHERE username = ?
realm .dataSource = $jof
realm .credentialsMatcher = $credentialsMatcher
securityManager.realm = $realm 

【讨论】:

我试过了,还是不能匹配输入的密码和数据库中存储的密码。

以上是关于如何在 Shiro 中使用 JdbcRealm 对提交的密码进行哈希处理?的主要内容,如果未能解决你的问题,请参考以下文章

shiro学习笔记_0300_jdbcRealm和认证策略

shiro框架学习-4- Shiro内置JdbcRealm

shiro,使用第三方jdbcRealm连接数据库操作

Shiro JdbcRealm 授权的表模式?

Shiro Spring JDBCRealm 身份验证和授权

shiro之 JdbcRealm及Authentication Strategy