DefaultWebSecurityManager类主要定义了设置subjectDao,获取会话模式,设置会话模式,设置会话管理器,是否是http会话模式等操作,它继承了DefaultSecurityManager类,实现了WebSecurityManager接口,现对其解析如下:
1.WebSecurityManager接口
可以参考WebSecurityManager接口源码解析,里面只有一个方法,定义了是否http会话模式。
2.DefaultSecurityManager类
可以参考DefaultSecurityManager类源码解析,里面主要定义了登录,创建subject,登出等操作。
3.DefaultWebSecurityManager类
3.1.数据属性
public static final String HTTP_SESSION_MODE = "http";//http会话模式
public static final String NATIVE_SESSION_MODE = "native";//本地会话模式
private String sessionMode;//会话模式
3.2.构造方法
public DefaultWebSecurityManager() {
super();
((DefaultSubjectDAO) this.subjectDAO).setSessionStorageEvaluator(new DefaultWebSessionStorageEvaluator());
this.sessionMode = HTTP_SESSION_MODE;
setSubjectFactory(new DefaultWebSubjectFactory());
setRememberMeManager(new CookieRememberMeManager());
setSessionManager(new ServletContainerSessionManager());
}
3.3.构造方法
public DefaultWebSecurityManager(Realm singleRealm) {
this();
setRealm(singleRealm);
}
3.4.构造方法
public DefaultWebSecurityManager(Collection<Realm> realms) {
this();
setRealms(realms);
}
3.5.构造subject上下文
protected SubjectContext createSubjectContext() {
return new DefaultWebSubjectContext();
}
3.6.设置subjectDao并给session存储执行器设置会话管理器
public void setSubjectDAO(SubjectDAO subjectDAO) {
super.setSubjectDAO(subjectDAO);
applySessionManagerToSessionStorageEvaluatorIfPossible();
}
3.7.设置完会话管理器后的操作(设置完会话管理器,并给session存储执行器设置会话管理器)
protected void afterSessionManagerSet() {
super.afterSessionManagerSet();
applySessionManagerToSessionStorageEvaluatorIfPossible();
}
3.8.给session存储执行器设置会话管理器
private void applySessionManagerToSessionStorageEvaluatorIfPossible() {
SubjectDAO subjectDAO = getSubjectDAO();
if (subjectDAO instanceof DefaultSubjectDAO) {
SessionStorageEvaluator evaluator = ((DefaultSubjectDAO)subjectDAO).getSessionStorageEvaluator();
if (evaluator instanceof DefaultWebSessionStorageEvaluator) {
((DefaultWebSessionStorageEvaluator)evaluator).setSessionManager(getSessionManager());
}
}
}
3.9.拷贝上下文环境(它覆盖了DefaultSecurityManager类的方法)
protected SubjectContext copy(SubjectContext subjectContext) {
if (subjectContext instanceof WebSubjectContext) {
return new DefaultWebSubjectContext((WebSubjectContext) subjectContext);
}
return super.copy(subjectContext);
}
3.10.获取session模式
public String getSessionMode() {
return sessionMode;
}
3.11.根据session模式创建servletContainerSessionManager或者DefaultWebSessionManager
public void setSessionMode(String sessionMode) {
log.warn("The 'sessionMode' property has been deprecated. Please configure an appropriate WebSessionManager " +
"instance instead of using this property. This property/method will be removed in a later version.");
String mode = sessionMode;
if (mode == null) {
throw new IllegalArgumentException("sessionMode argument cannot be null.");
}
mode = sessionMode.toLowerCase();
if (!HTTP_SESSION_MODE.equals(mode) && !NATIVE_SESSION_MODE.equals(mode)) {
String msg = "Invalid sessionMode [" + sessionMode + "]. Allowed values are " +
"public static final String constants in the " + getClass().getName() + " class: '"
+ HTTP_SESSION_MODE + "' or '" + NATIVE_SESSION_MODE + "', with '" +
HTTP_SESSION_MODE + "' being the default.";
throw new IllegalArgumentException(msg);
}
boolean recreate = this.sessionMode == null || !this.sessionMode.equals(mode);
this.sessionMode = mode;
if (recreate) {
LifecycleUtils.destroy(getSessionManager());
SessionManager sessionManager = createSessionManager(mode);
this.setInternalSessionManager(sessionManager);
}
}
3.12.设置会话管理器(它覆盖了DefaultSecurityManager的方法)
public void setSessionManager(SessionManager sessionManager) {
this.sessionMode = null;
if (sessionManager != null && !(sessionManager instanceof WebSessionManager)) {
if (log.isWarnEnabled()) {
String msg = "The " + getClass().getName() + " implementation expects SessionManager instances " +
"that implement the " + WebSessionManager.class.getName() + " interface. The " +
"configured instance is of type [" + sessionManager.getClass().getName() + "] which does not " +
"implement this interface.. This may cause unexpected behavior.";
log.warn(msg);
}
}
setInternalSessionManager(sessionManager);
}
3.13.设置会话管理器
private void setInternalSessionManager(SessionManager sessionManager) {
super.setSessionManager(sessionManager);
}
3.14.判断是否是http会话模式(它实现了WebSecurityManager接口的方法)
public boolean isHttpSessionMode() {
SessionManager sessionManager = getSessionManager();
return sessionManager instanceof WebSessionManager && ((WebSessionManager)sessionManager).isServletContainerSessions();
}
3.15.根据会话模式创建会话管理器(它覆盖了DefaultSecurityManager类的方法)
protected SessionManager createSessionManager(String sessionMode) {
if (sessionMode == null || !sessionMode.equalsIgnoreCase(NATIVE_SESSION_MODE)) {
log.info("{} mode - enabling ServletContainerSessionManager (HTTP-only Sessions)", HTTP_SESSION_MODE);
return new ServletContainerSessionManager();
} else {
log.info("{} mode - enabling DefaultWebSessionManager (non-HTTP and HTTP Sessions)", NATIVE_SESSION_MODE);
return new DefaultWebSessionManager();
}
}
3.16.根据subject上下文获取会话key(它覆盖了DefaultSecurityManager类的方法)
protected SessionKey getSessionKey(SubjectContext context) {
if (WebUtils.isWeb(context)) {
Serializable sessionId = context.getSessionId();
ServletRequest request = WebUtils.getRequest(context);
ServletResponse response = WebUtils.getResponse(context);
return new WebSessionKey(sessionId, request, response);
} else {
return super.getSessionKey(context);
}
}
3.17.退出登录之前的操作(它覆盖了DefaultSecurityManager类的方法)
protected void beforeLogout(Subject subject) {
super.beforeLogout(subject);
removeRequestIdentity(subject);
}
3.18.移除身份信息
protected void removeRequestIdentity(Subject subject) {
if (subject instanceof WebSubject) {
WebSubject webSubject = (WebSubject) subject;
ServletRequest request = webSubject.getServletRequest();
if (request != null) {
request.setAttribute(ShiroHttpServletRequest.IDENTITY_REMOVED_KEY, Boolean.TRUE);
}
}
}