Shiro 中的 CredentialsMatcher 与 Pa
CredentialsMatcher 接口
CredentialsMatcher 接口只声明了一个方法boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info);用于对AuthenticationToken和AuthenticationInfo进行匹配认证。其实执行过程中,主要是对两者中的credentials属性进行匹配。
CredentialsMatcher的继承结构
public interface CredentialsMatcher {
boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info);
}
CodecSupport 抽象类
CodecSupport这个抽象类,是实现了一个很多静态工具方法的类,充满了String和Char Byte之间的转换。需要两个参数的方法,后面的String参数是用来指定编码的。
CodecSupport中的方法
SimpleCredentialsMatcher 类
SimpleCredentialsMatcher 直接实现了CredentialsMatcher接口,只是对简单的进行了扩展;没有使用到密码和散列算法,仅仅是对AuthenticationToken和AuthenticationInfo中的credentials进行了比较。匹配返回true,否则返回fasle。因为在AuthenticationToken和AuthenticationInfo中的credentials都是Object,所以可以在外面对其进行加工,如果达到一次高级目的。可参考下面的代码,制定扩展方式:
if (isByteSource(tokenCredentials) && isByteSource(accountCredentials)) {
if (log.isDebugEnabled()) {
log.debug("Both credentials arguments can be easily converted to byte arrays. Performing " +
"array equals comparison");
}
byte[] tokenBytes = toBytes(tokenCredentials);
byte[] accountBytes = toBytes(accountCredentials);
return MessageDigest.isEqual(tokenBytes, accountBytes);
} else {
return accountCredentials.equals(tokenCredentials);
}
AllowAllCredentialsMatcher 类
AllowAllCredentialsMatcher 就是一个逗逼,你要是用了他在生产环境中,我相信你们老板会哭的。因为无论你给他什么,它都会告诉:“哦,是的!”。
public class AllowAllCredentialsMatcher implements CredentialsMatcher {
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
return true;
}
}
HashedCredentialsMatcher 类
HashedCredentialsMatcher 继承自 SimpleCredentialsMatcher 并进行了扩展。
- 支持Hash算法:Md2、Md5、Sha1、Sha256、Sha384、Sha512;
- 支持多次迭代Hash,默认为1次;
- 支持加盐Hash,当然用与不用完全在于你自己;
CredentialsMatcher的继承结构图中后面那些已经废弃的类,并不是说他们不再安全,而是因为他们完全可以被HashedCredentialsMatcher所替代。
PasswordMatcher
PasswordMatcher需要配合PasswordService来用。具体内容参见后面的PasswordService小节吧。
小结
平常使用时HashedCredentialsMatcher已经足以满足我们的需求。如果需要更复杂的密码方式,可以在自己定义的Realm的doGetAuthenticationInfo方法中把密码计算好,然后使用SimpleCredentialsMatcher。也可以通过扩展SimpleCredentialsMatcher的方实现。具体怎么用就看个人喜好了。
PasswordService 接口
public interface PasswordService {
String encryptPassword(Object plaintextPassword) throws IllegalArgumentException;
boolean passwordsMatch(Object submittedPlaintext, String encrypted);
}
public interface HashingPasswordService extends PasswordService {
Hash hashPassword(Object plaintext) throws IllegalArgumentException;
boolean passwordsMatch(Object plaintext, Hash savedPasswordHash);
}
PasswordService 和HashingPasswordService都是接口,他们有唯一一个实现类DefaultPasswordService。但在这个实现类中所用到的其他类(如:Hash、HashService、HashFormat等)又是一个庞大的族群,就不做介绍了。
下面把所有涉及到的类及其继承关系罗列如下:
HashService -> ConfigurableHashService -> DefaultHashService
-> Base64Format
HashFormat -> ParsableHashFormat -> Shiro1CryptFormat
-> ModularCryptFormat ->
-> HexFormat
-> Md5Hash
-> Md2Hash
Hash -> AbstractHash -> SimpleHash -> Sha1Hash
-> Sha256Hash
-> Sha384Hash
-> Sha512Hash
继承关系
-
HashFormat常用的是Shiro1CryptFormat; -
HashService常用的是DefaultHashService; -
Hash常用的是SimpleHash。
如果这些满足不了你的需求,还可以自己扩展。