2021SC@SDUSC
DefaultSubjectDAO类图如下
私有变量
sessionStorageEvaluator
private SessionStorageEvaluator sessionStorageEvaluator;
确定一个主题的会话是否可用于存储主题自己的状态的评估器
方法分析
isSessionStorageEnabled
protected boolean isSessionStorageEnabled(Subject subject) {
return getSessionStorageEvaluator().isSessionStorageEnabled(subject);
}
确定主题的会话是否将用于保持主题状态。此实现仅委托给内部 SessionStorageEvaluator(默认情况下为 DefaultSessionStorageEvaluator)。
getSessionStorageEvaluator
public SessionStorageEvaluator getSessionStorageEvaluator() {
return sessionStorageEvaluator;
}
返回 SessionStorageEvaluator,它将确定 Subject 的状态是否可以保留在 Subject 的会话中。默认实例DefaultSessionStorageEvaluator
setSessionStorageEvaluator
public void setSessionStorageEvaluator(SessionStorageEvaluator sessionStorageEvaluator) {
this.sessionStorageEvaluator = sessionStorageEvaluator;
}
设置 SessionStorageEvaluator 将确定 Subject 的状态是否可以保留在 Subject 的会话中。默认实例是 DefaultSessionStorageEvaluator。
save
public Subject save(Subject subject) {
if (isSessionStorageEnabled(subject)) {
saveToSession(subject);
} else {
log.trace("Session storage of subject state for Subject [{}] has been disabled: identity and " +
"authentication state are expected to be initialized on every request or invocation.", subject);
}
return subject;
}
仅当 sessionStorageEnabled(subject) 时才将主题的状态保存到主题的 session。如果未为特定 Subject 启用会话存储,则此方法不执行任何操作。
saveToSession
protected void saveToSession(Subject subject) {
//performs merge logic, only updating the Subject's session if it does not match the current state:
mergePrincipals(subject);
mergeAuthenticationState(subject);
}
将主题的状态(它的主体和身份验证状态)保存到它的 SubjectgetSession() 会话。会话可以在以后检索(通常来自 SessionManager 用于重新创建 Subject 实例。
isEmpty
private static boolean isEmpty(PrincipalCollection pc) {
return pc == null || pc.isEmpty();
}
判断PrincipalCollection是否为空
mergePrincipals
protected void mergePrincipals(Subject subject) {
//merge PrincipalCollection state:
PrincipalCollection currentPrincipals = null;
//SHIRO-380: added if/else block - need to retain original (source) principals
//This technique (reflection) is only temporary - a proper long term solution needs to be found,
//but this technique allowed an immediate fix that is API point-version forwards and backwards compatible
//
//A more comprehensive review / cleaning of runAs should be performed for Shiro 1.3 / 2.0 +
if (subject.isRunAs() && subject instanceof DelegatingSubject) {
try {
Field field = DelegatingSubject.class.getDeclaredField("principals");
field.setAccessible(true);
currentPrincipals = (PrincipalCollection)field.get(subject);
} catch (Exception e) {
throw new IllegalStateException("Unable to access DelegatingSubject principals property.", e);
}
}
if (currentPrincipals == null || currentPrincipals.isEmpty()) {
currentPrincipals = subject.getPrincipals();
}
Session session = subject.getSession(false);
if (session == null) {
if (!isEmpty(currentPrincipals)) {
session = subject.getSession();
session.setAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY, currentPrincipals);
}
// otherwise no session and no principals - nothing to save
} else {
PrincipalCollection existingPrincipals =
(PrincipalCollection) session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
if (isEmpty(currentPrincipals)) {
if (!isEmpty(existingPrincipals)) {
session.removeAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
}
// otherwise both are null or empty - no need to update the session
} else {
if (!currentPrincipals.equals(existingPrincipals)) {
session.setAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY, currentPrincipals);
}
// otherwise they're the same - no need to update the session
}
}
}
将主题的当前SubjectgetPrincipals 与任何可用会话中的任何内容合并。如果会话与当前主体状态不匹配,则仅更新主题的会话。
mergeAuthenticationState
protected void mergeAuthenticationState(Subject subject) {
Session session = subject.getSession(false);
if (session == null) {
if (subject.isAuthenticated()) {
session = subject.getSession();
session.setAttribute(DefaultSubjectContext.AUTHENTICATED_SESSION_KEY, Boolean.TRUE);
}
//otherwise no session and not authenticated - nothing to save
} else {
Boolean existingAuthc = (Boolean) session.getAttribute(DefaultSubjectContext.AUTHENTICATED_SESSION_KEY);
if (subject.isAuthenticated()) {
if (existingAuthc == null || !existingAuthc) {
session.setAttribute(DefaultSubjectContext.AUTHENTICATED_SESSION_KEY, Boolean.TRUE);
}
//otherwise authc state matches - no need to update the session
} else {
if (existingAuthc != null) {
//existing doesn't match the current state - remove it:
session.removeAttribute(DefaultSubjectContext.AUTHENTICATED_SESSION_KEY);
}
//otherwise not in the session and not authenticated - no need to update the session
}
}
}
将主题的当前身份验证状态与任何可用会话中的任何内容合并。如果会话与当前身份验证状态不匹配,则仅更新主题的会话。
removeFromSession
protected void removeFromSession(Subject subject) {
Session session = subject.getSession(false);
if (session != null) {
session.removeAttribute(DefaultSubjectContext.AUTHENTICATED_SESSION_KEY);
session.removeAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
}
}
从主题的会话中删除任何现有的主题状态(如果会话存在)。如果会话不存在,则此方法不执行任何操作。
delete
public void delete(Subject subject) {
removeFromSession(subject);
}
从主题的会话中删除任何现有的主题状态(如果会话存在)。