Shiro 提供了完整的企业级会话管理功能,不管JavaSE 还是 JavaEE 环境都可以使用,提供了会话管理、会话事件监听、会话存储/持久化、容器无关的集群、失效/过期支持、对 Web 的透明支持、SSO 单点登录的支持等特性。即直接使用 Shiro 的会话管理可以直接替换如 Web 容器的会话管理。
一、基础组件
1、会话管理器
会话管理器管理着应用中所有 Subject 的会话的创建、维护、删除、失效、验证等工作。是Shiro 的核心组件,顶层组件 SecurityManager 直接继承了 SessionManager,且提供了SessionsSecurityManager实现直接把会话管理委托给相应的SessionManager.
DefaultSessionManager:DefaultSecurityManager 默认使用的会话管理器,用于JavaSE环境的session管理。
ServletContainerSessionManager:DefaultWebSecurityManager 默认使用的会话管理器,用于Web环境,直接使用的Servlet容器的会话。
DefaultWebSessionManager:用于Web环境,可以替换 ServletContainerSessionManager,废弃了Servlet容器的会话管理;通过此可以实现我们自己的session管理。
2、会话监听器
//会话监听器用于监听会话创建、过期及停止事件
public class MySessionListener1 implementsSessionListener {
@Overridepublic void onStart(Session session) {//会话创建时触发
System.out.println("会话创建:" +session.getId());
}
@Overridepublic void onExpiration(Session session) {//会话过期时触发
System.out.println("会话过期:" +session.getId());
}
@Overridepublic void onStop(Session session) {//退出/会话过期时触发
System.out.println("会话停止:" +session.getId());
}
}//如果只想监听某一个事件,可以继承 SessionListenerAdapter 实现
public class MySessionListener2 extendsSessionListenerAdapter {
@Overridepublic voidonStart(Session session) {
System.out.println("会话创建:" +session.getId());
}
}
二、管理会话
所谓会话,即用户访问应用时保持的连接关系,在多次交互中应用能够识别出当前访问的用户是谁,且可以在多次交互中保存一些数据。如访问一些网站时登录成功后,网站可以记住用户,且在退出之前都可以识别当前用户是谁。
1、会话的创建
sessionFactory 是创建会话的工厂,根据相应的Subject上下文信息来创建会话;默认提供了SimpleSessionFactory用来创建SimpleSession会话。
登录时创建会话的流程
首次未登录请求
DelegatingFilterProxy::doFilter
-->DelegatingFilterProxy::invokeDelegate
-->OncePerRequestFilter::doFilter 先执行全局拦截器
-->AbstractShiroFilter::doFilterInternal创建Subject 未登录时 session=null
-->DelegatingSubject::execute紧接着执行一堆过滤器
-->AdviceFilter::doFilterInternal
-->AccessControlFilter::saveRequestAndRedirectToLogin
-->AccessControlFilter::saveRequest
-->WebUtils::saveRequest保存请求信息时创建sesssion
-->DelegatingSubject::getSession()
-->DelegatingSubject::getSession(true)
-->DefaultWebSecurityManager::start //启动会话
-->AbstractNativeSessionManager::start
-->AbstractValidatingSessionManager::createSession //ValidatingSessionManager
-->DefaultSessionManager::doCreateSession