2021SC@SDUSC
AbstractRememberMeManager类综述
AbstractRememberMeManager类实现了RememberMeManager接口
静态变量:
private static final Logger log = LoggerFactory.getLogger(AbstractRememberMeManager.class);
私有变量:
private Serializer<PrincipalCollection> serializer;
private CipherService cipherService;
private byte[] encryptionCipherKey;
private byte[] decryptionCipherKey;
提供以下方法:
- getSerializer
- setSerializer
- getCipherService
- setCipherService
- getEncryptionCipherKey
- setCipherService
- getEncryptionCipherKey
- setEncryptionCipherKey
- getDecryptionCipherKey
- setDecryptionCipherKey
- getCipherKey
- setCipherKey
- forgetIdentity
- isRememberMe
- onSuccessfulLogin
- rememberIdentity
- getIdentityToRemember
- rememberIdentity
- convertPrincipalsToBytes
- rememberSerializedIdentity
- getRememberedPrincipals
- getRememberedSerializedIdentity
- convertBytesToPrincipals
- onRememberedPrincipalFailure
- encrypt
- decrypt
- serialize
- deserialize
- onFailedLogin
- onLogout
变量分析
静态变量log
private static final Logger log = LoggerFactory.getLogger(AbstractRememberMeManager.class);
从日志工厂获得一个关于AbstractRememberMeManager类得日志
私有变量
serializer
private Serializer<PrincipalCollection> serializer;
用于将PrincipalCollection实例转换为字节数组或从字节数组转换为PrincipalCollection的变量
cipherService
private CipherService cipherService;
用于加密/解密序列化字节数组以增加安全性
encryptionCipherKey
private byte[] encryptionCipherKey;
加密数据时与密码一起使用的密码加密密钥
decryptionCipherKey
private byte[] decryptionCipherKey;
解密数据时与密码一起使用的密码解密密钥
方法分析
getSerializer
获得Serializer
setSerializer
设置Serializer
getCipherService
获得CipherService
setCipherService
设置CipherService
getEncryptionCipherKey
获得EncryptionCipherKey
getEncryptionCipherKey
获得EncryptionCipherKey
setEncryptionCipherKey
设置EncryptionCipherKey
getDecryptionCipherKey
获得DecryptionCipherKey
setDecryptionCipherKey
设置DecryptionCipherKey
getCipherKey
public byte[] getCipherKey() {
return getEncryptionCipherKey();
}
获得CipherKey
只能用于对称密码
即DecryptionCipherKey和EncryptionCipherKey相同
setCipherKey
public void setCipherKey(byte[] cipherKey) {
setEncryptionCipherKey(cipherKey);
setDecryptionCipherKey(cipherKey);
}
设置CipherKey
只能在DecryptionCipherKey和EncryptionCipherKey相同时使用
forgetIdentity
protected abstract void forgetIdentity(Subject subject);
抽象方法
移除已经记住的任何实例
isRememberMe
protected boolean isRememberMe(AuthenticationToken token) {
return token != null && (token instanceof RememberMeAuthenticationToken) &&
((RememberMeAuthenticationToken) token).isRememberMe();
}
明确是否该为指定token执行rememberMe操作
onSuccessfulLogin
public void onSuccessfulLogin(Subject subject, AuthenticationToken token, AuthenticationInfo info) {
//always clear any previous identity:
forgetIdentity(subject);
//now save the new identity:
if (isRememberMe(token)) {
rememberIdentity(subject, token, info);
} else {
if (log.isDebugEnabled()) {
log.debug("AuthenticationToken did not indicate RememberMe is requested. " +
"RememberMe functionality will not be executed for corresponding account.");
}
}
}
对成功的登录尝试作出反应,首先总是忘记以前的任何尝试存储的身份。然后,如果令牌是RememberMe令牌,则将记住关联的标识,以便在新用户会话期间稍后检索。
rememberIdentity
public void rememberIdentity(Subject subject, AuthenticationToken token, AuthenticationInfo authcInfo) {
PrincipalCollection principals = getIdentityToRemember(subject, authcInfo);
rememberIdentity(subject, principals);
}
记住主题的唯一标识,以便以后检索。
getIdentityToRemember
protected PrincipalCollection getIdentityToRemember(Subject subject, AuthenticationInfo info) {
return info.getPrincipals();
}
返回并忽略参数。
convertPrincipalsToBytes
protected byte[] convertPrincipalsToBytes(PrincipalCollection principals) {
byte[] bytes = serialize(principals);
if (getCipherService() != null) {
bytes = encrypt(bytes);
}
return bytes;
}
将给定的主体集合转换为字节数组,该字节数组将在以后被持久化为记住
rememberSerializedIdentity
protected abstract void rememberSerializedIdentity(Subject subject, byte[] serialized);
抽象方法
将标识字节记住,以便稍后通过方法进行检索。
getRememberedPrincipals
public PrincipalCollection getRememberedPrincipals(SubjectContext subjectContext) {
PrincipalCollection principals = null;
byte[] bytes = null;
try {
bytes = getRememberedSerializedIdentity(subjectContext);
//SHIRO-138 - only call convertBytesToPrincipals if bytes exist:
if (bytes != null && bytes.length > 0) {
principals = convertBytesToPrincipals(bytes, subjectContext);
}
} catch (RuntimeException re) {
principals = onRememberedPrincipalFailure(re, subjectContext);
} finally {
ByteUtils.wipe(bytes);
}
return principals;
}
通过首先获取记住的序列化字节数组来实现接口方法。然后它转换它们并返回重新构造的。如果无法获得记住的主体,则返回。
getRememberedSerializedIdentity
protected abstract byte[] getRememberedSerializedIdentity(SubjectContext subjectContext);
基于给定的主题上下文数据,检索以前持久化的序列化标识,或者如果没有可用数据。
convertBytesToPrincipals
protected PrincipalCollection convertBytesToPrincipals(byte[] bytes, SubjectContext subjectContext) {
if (getCipherService() != null) {
bytes = decrypt(bytes);
}
return deserialize(bytes);
}
如果cipherService可用,它将首先用于解密字节数组。然后对字节进行反序列化,然后返回
onRememberedPrincipalFailure
protected PrincipalCollection onRememberedPrincipalFailure(RuntimeException e, SubjectContext context) {
if (log.isWarnEnabled()) {
String message = "There was a failure while trying to retrieve remembered principals. This could be due to a " +
"configuration problem or corrupted principals. This could also be due to a recently " +
"changed encryption key, if you are using a shiro.ini file, this property would be " +
"'securityManager.rememberMeManager.cipherKey' see: http://shiro.apache.org/web.html#Web-RememberMeServices. " +
"The remembered identity will be forgotten and not used for this request.";
log.warn(message);
}
forgetIdentity(context);
//propagate - security manager implementation will handle and warn appropriately
throw e;
}
在索引subject时抛出异常时调用
encrypt
protected byte[] encrypt(byte[] serialized) {
byte[] value = serialized;
CipherService cipherService = getCipherService();
if (cipherService != null) {
ByteSource byteSource = cipherService.encrypt(serialized, getEncryptionCipherKey());
value = byteSource.getBytes();
}
return value;
}
使用配置的cipherService加密字节数组。
decrypt
protected byte[] decrypt(byte[] encrypted) {
byte[] serialized = encrypted;
CipherService cipherService = getCipherService();
if (cipherService != null) {
ByteSourceBroker broker = cipherService.decrypt(encrypted, getDecryptionCipherKey());
serialized = broker.getClonedBytes();
}
return serialized;
}
使用配置的cipherService解密字节数组。
serialize
protected byte[] serialize(PrincipalCollection principals) {
return getSerializer().serialize(principals);
}
通过使用serialize方法将给定主体序列化为字节数组来序列化这些主体。
deserialize
protected PrincipalCollection deserialize(byte[] serializedIdentity) {
return getSerializer().deserialize(serializedIdentity);
}
通过deserialize放序列化字节数组
onFailedLogin
public void onFailedLogin(Subject subject, AuthenticationToken token, AuthenticationException ae) {
forgetIdentity(subject);
}
如果登录失败,就忘掉subject先前的所有标识
onLogout
public void onLogout(Subject subject) {
forgetIdentity(subject);
}
如果退出,则忘掉先前保存的所有标识