前言
shiro提供了完整的会话功能,不依赖于底层容器,即直接使用shiro的会话管理可以直接替换掉web容器的会话管理
会话
所谓会话,即用户访问应用时保持的连接关系,在多次交互中应用能够识别出当前访问的用户是谁,且可以在多次交互中保存一些数据。如访问一些网站时登录成功后,网站可以记住用户,且在退出之前都可以识别当前用户是谁。
获取会话
Subject subject = SecurityUtils.getSubject();
Session session = subject.getSession();
获取当前会话的唯一标识
session.getId();
获取当前Subject的主机地址
session.getHost();
获取/设置当前Session的过期时间
session.getTimeout();
session.setTimeout(毫秒);
获取会话的启动时间及最后访问时间
session.getStartTimestamp();
session.getLastAccessTime();
更新会话最后访问时间及销毁会话
session.touch();
session.stop();
当Subject.logout()时会自动调用stop方法来销毁会话
设置/获取/删除会话属性
session.setAttribute(“key”, “WORD”);
session.getAttribute(“key”);
session.removeAttribute(“key”);
会话管理器
会话管理器管理着应用中所有subject的会话的创建、维护、删除、失效、验证等工作。它是shiro的核心,顶层组件SecurityManager直接继承了SessionManager,且提供了SessionsSecurityManager实现直接把会话管理委托给相应的SessionManager,DefaultSecurityManager及DefaultWebSecurityManager默认SecurityManager都继承了SessionsSecurityManager。
SecurityManager
Session start(SessionContext context); //启动会话
Session getSession(SessionKey key) throws SessionException; //根据会话Key获取会话
WebSessionManager
boolean isServletContainerSessions();//是否使用Servlet容器的会话
ValidatingSessionManager
void validateSessions();//验证所有会话是否过期
Shiro提供了三个默认实现:
DefaultSessionManager:DefaultSecurityManager使用的默认实现,用于JavaSE环境;
ServletContainerSessionManager:DefaultWebSecurityManager使用的默认实现,用于Web环境,其直接使用Servlet容器的会话;
DefaultWebSessionManager:用于Web环境的实现,可以替代ServletContainerSessionManager,自己维护着会话,直接废弃了Servlet容器的会话管理。
全局会话时间
在web.xml中设置(单位:分钟)
30
会话监听器
会话监听器用于监听会话创建、过期及停止事件:
|
|
如果只想监听某一个事件,可以继承SessionListenerAdapter实现:
|
|
会话存储/持久化
Shiro提供SessionDAO用于会话的CRUD
//如DefaultSessionManager在创建完session后会调用该方法;如保存到关系数据库/文件系统/NoSQL数据库;即可以实现会话的持久化;返回会话ID;主要此处返回的ID.equals(session.getId()); Serializable create(Session session); //根据会话ID获取会话 Session readSession(Serializable sessionId) throws UnknownSessionException; //更新会话;如更新会话最后访问时间/停止会话/设置超时时间/设置移除属性等会调用 void update(Session session) throws UnknownSessionException; //删除会话;当会话过期/会话停止(如用户退出时)会调用 void delete(Session session); //获取当前所有活跃用户,如果用户量多此方法影响性能 Collection<Session> getActiveSessions();
AbstractSessionDAO提供了SessionDAO的基础实现,如生成会话ID等;CachingSessionDAO提供了对开发者透明的会话缓存的功能,只需要设置相应的CacheManager即可;MemorySessionDAO直接在内存中进行会话维护;而EnterpriseCacheSessionDAO提供了缓存功能的会话维护,默认情况下使用MapCache实现,内部使用ConcurrentHashMap保存缓存的会话。
如果自定义实现SessionDAO,继承CachingSessionDAO即可
|
|
会话验证
Shiro提供了会话验证调度器,用于定期的验证会话是否已过期,如果过期将停止会话,Shiro提供了会话验证调度器SessionValidationScheduler来验证
|
|
sessionFactory
sessionFactory是创建会话的工厂,根据相应的Subject上下文信息来创建会话;默认提供了SimpleSessionFactory用来创建SimpleSession会话。
自定义一个session
|
|
自定义SessionFactory