Shiro 中的 CredentialsMatcher 与 Pa
CredentialsMatcher 接口
CredentialsMatcher
接口只声明了一个方法boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info);
用于对AuthenticationToken
和AuthenticationInfo
进行匹配认证。其实执行过程中,主要是对两者中的credentials
属性进行匹配。
public interface CredentialsMatcher {
boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info);
}
CodecSupport 抽象类
CodecSupport
这个抽象类,是实现了一个很多静态工具方法的类,充满了String
和Char Byte
之间的转换。需要两个参数的方法,后面的String参数是用来指定编码的。
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
。
如果这些满足不了你的需求,还可以自己扩展。