您的位置:首页 > 编程语言 > PHP开发

Shiro 1.2新功能DefaultPasswordService解惑

2015-06-14 16:33 573 查看
最开始学习shiro的时候需要自己保存User的salt, 最近系统升级,使用了Shiro1.3发现在1.2的时候Shiro提供了新的DefaultPasswordService来简化Password encode/match工作。很好奇为啥不在需要自己保存User的salt,查看了defaultpasswordservice的源代码,发现了其中的奥秘,具体看Shiro的代码(关注*部分),主要是重新构建Hash,然后从Hash中获取salt来做提交密码的hash,比较计算出来的hash和存储hash是否一致。

public boolean More ...passwordsMatch(Object submittedPlaintext, String saved) {
ByteSource plaintextBytes = createByteSource(submittedPlaintext);

if (saved == null || saved.length() == 0) {
return plaintextBytes == null || plaintextBytes.isEmpty();
} else {
if (plaintextBytes == null || plaintextBytes.isEmpty()) {
return false;
}
}

//First check to see if we can ***reconstitute the original hash*** - this allows us to
//perform password hash comparisons even for previously saved passwords that don't
//match the current HashService configuration values.  This is a very nice feature
//for password comparisons because it ensures backwards compatibility even after
//configuration changes.
***HashFormat discoveredFormat = this.hashFormatFactory.getInstance(saved);***

<strong>if (discoveredFormat != null && discoveredFormat instanceof ParsableHashFormat) {

ParsableHashFormat parsableHashFormat = (ParsableHashFormat)discoveredFormat;
**Hash savedHash = parsableHashFormat.parse(saved);**

return ***passwordsMatch(submittedPlaintext, savedHash)***;
}</strong>

//If we're at this point in the method's execution, We couldn't reconstitute the original hash.
//So, we need to ***hash the submittedPlaintext using current HashService configuration and then
//compare the formatted output with the saved string.  This will correctly compare passwords***,
//***but does not allow changing the HashService configuration without breaking previously saved
//passwords***:

//The saved text value can't be reconstituted into a Hash instance.  We need to format the
//submittedPlaintext and then compare this formatted value with the saved value:
HashRequest request = createHashRequest(plaintextBytes);
Hash computed = this.hashService.computeHash(request);
String formatted = this.hashFormat.format(computed);

return saved.equals(formatted);
}
public boolean passwordsMatch(Object plaintext, Hash saved) {
ByteSource plaintextBytes = createByteSource(plaintext);

if (saved == null || saved.isEmpty()) {
return plaintextBytes == null || plaintextBytes.isEmpty();
} else {
if (plaintextBytes == null || plaintextBytes.isEmpty()) {
return false;
}
}

HashRequest request = ***buildHashRequest(plaintextBytes, saved);***

Hash computed = this.hashService.computeHash(request);

return saved.equals(computed);
}
protected HashRequest buildHashRequest(ByteSource plaintext, Hash saved) {
//keep everything from the saved hash except for the source:
return new HashRequest.Builder().setSource(plaintext)
//now use the existing saved data:
.setAlgorithmName(saved.getAlgorithmName())
.***setSalt(saved.getSalt())***
.setIterations(saved.getIterations())
.build();
}


要使用defaultpasswordService非常简单就是简单的spring bean,当然你可以通过注入改变迭代次数和加密算法。

<bean name="passwordService" class="org.apache.shiro.authc.credential.DefaultPasswordService" />
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: