session与cookie创建,是在第一次进入shiro域时,访问jsp页面之前。
此时调用了getSession方法。
public HttpSession getSession(){
return getSession(true);
}
public HttpSession getSession(boolean create) {
HttpSession httpSession;
if(this.isHttpSessions()) {
httpSession = super.getSession(false);
if(httpSession == null && create) {
if(!WebUtils._isSessionCreationEnabled(this)) {
throw this.newNoSessionCreationException();
}
httpSession = super.getSession(create);
}
} else {
if(this.session == null) {
boolean existing = this.getSubject().getSession(false) != null;
Session shiroSession = this.getSubject().getSession(create);
if(shiroSession != null) {
this.session = new ShiroHttpSession(shiroSession, this, this.servletContext);
if(!existing) {
this.setAttribute(REFERENCED_SESSION_IS_NEW, Boolean.TRUE);
}
}
}
httpSession = this.session;
}
return httpSession;
}
实际上调用了sessionDAO创建session,sessionDAO一般是框架用户自定义的。
@Override
protected Session createSession(SessionContext sessionContext) throws AuthorizationException {
Session session= this.getSessionFactory().createSession(sessionContext);
this.sessionDAO.create(session);
return session;
}
使用这个方法创建了cookie,并把sessionid保存到了cookie中
private void storeSessionId(Serializable currentId, HttpServletRequest request, HttpServletResponse response) {
if(currentId == null) {
String msg = "sessionId cannot be null when persisting for subsequent requests.";
throw new IllegalArgumentException(msg);
} else {
Cookie template=this.getSessionIdCookie();
Cookie cookie = new SimpleCookie(template);
String idString = currentId.toString();
cookie.setValue(idString);
cookie.saveTo(request, response);
}
}
在之后的每次访问中,session的获取如下:
@Override
public Subject createSubject(SubjectContext context) {
context = this.ensureSecurityManager(context);
context = this.resolveSession(context);
context = this.resolvePrincipals(context);
Subject subject = this.doCreateSubject(context);
this.save(subject);
return subject;
}
this.resolveContextSession(context);获取session
protected SubjectContext resolveSession(SubjectContext context) {
if(context.resolveSession() != null) {
log.debug("Context already contains a session. Returning.");
return context;
} else {
try {
Session session = this.resolveContextSession(context);
if(session != null) {
context.setSession(session);
}
} catch (InvalidSessionException var3) {
log.debug("Resolved SubjectContext context session is invalid. Ignoring and creating an anonymous (session-less) Subject instance.", var3);
}
return context;
}
}
通过DefaultWebSessionManager的这个方法从cookie中读取sesionid,然后通过 Session session = this.sessionDAO.readSession(sessionId);用户自定义的sessiondao中读取session。
public Serializable getSessionId(SessionKey key) {
Serializable id = super.getSessionId(key);
if(id == null && WebUtils.isWeb(key)) {
ServletRequest request = WebUtils.getRequest(key);
ServletResponse response = WebUtils.getResponse(key);
id = this.getSessionId(request, response);
}
return id;
}