【发布时间】:2012-09-17 09:02:57
【问题描述】:
我正在使用带有自定义 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 使用盐?
【问题讨论】:
标签: java authentication shiro