我使用 Apache Shiro 和自定义 JDBC 领域来从数据库中检索用户的盐、密码、哈希算法名称和哈希迭代次数,这些数据都存储为单独的列。
问题是我不确定在使用 PasswordMatcher 验证用户密码与数据库中存储的密码是否匹配时应该如何处理从数据库检索到的盐。
当使用 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(Object SubmittedPlaintext, String saving) 方法时,名为的对象request
包含以下内容
algorithmName=null
iterations=0
salt=null
source=cGFzc3dvcmQ=
第 161 行的下一行代码调用computeHash(request)
在DefaultHashService.java的时候该方法computeHash(HashRequest request)
被调用,第 155 行和第 157 行变量algorithmName 和iterations 被正确设置为SHA-256
and 1
分别。第 159 行方法getPublicSalt(request)
被调用但返回 null。
有没有其他人使用 Shiro 的 PasswordMatcher 与自定义领域,如果你如何告诉 Shiro 使用盐?