我正在使用带有自定义 JDBC 领域的 Apache Shiro 从数据库中检索用户的盐、密码、哈希算法名称和哈希迭代次数,这些都存储为单独的列。
问题是我不确定在使用 PasswordMatcher 验证用户的密码是否与存储在数据库中的密码匹配时,我应该如何处理从数据库中检索到的 salt。
使用 HashedCredentialsMatcher 时,盐是使用该setCredentialsSalt
方法设置的,但是在使用 PasswordMatcher 而不是 HashedCredentialsMatcher 时,情况似乎并非如此。
我在自定义 JDBC 领域中使用的代码如下
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//code to retrieve user details from database removed for brevity
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, passwdSalt.password, getName());
info.setCredentialsSalt(new SimpleByteSource(passwdSalt.salt));
DefaultPasswordService passwordService = new DefaultPasswordService();
DefaultHashService hashService = new DefaultHashService();
PasswordMatcher passwordMatcher = new PasswordMatcher();
hashService.setHashAlgorithmName(passwdSalt.hashAlgorithmName);
hashService.setHashIterations(passwdSalt.hashIterations);
passwordService.setHashService(hashService);
passwordMatcher.setPasswordService(passwordService);
setCredentialsMatcher(passwordMatcher);
return info;
}
单步执行代码后,我确认问题肯定是由于在对用户输入的密码进行哈希处理时未使用盐,以便将其与数据库中的哈希密码进行匹配。在 DefaultPasswordService.java 中,当在第 160 行调用方法 passwordsMatch(ObjectmittedPlaintext, String saved) 时,命名的对象request
包含以下内容
algorithmName=null
iterations=0
salt=null
source=cGFzc3dvcmQ=
第 161 行的下一行代码调用computeHash(request)
在 DefaultHashService.java 中,当computeHash(HashRequest request)
调用该方法时,在第 155 行和第 157 行,变量 algorithmName 和 iterations 分别正确设置为SHA-256
和1
。在第 159 行,该方法getPublicSalt(request)
被调用,但它返回 null。
有没有其他人使用 Shiro 的 PasswordMatcher 和自定义领域,如果你如何告诉 Shiro 使用盐?