Shiro Session管理——操作session
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Shiro Session管理——操作session相关的知识,希望对你有一定的参考价值。
参考技术A 我们可以看到这个框架图,我们的整个交互都是与security Manager做交互,而这里面就有一个Session Manager的管理器,Shiro当然内置了实现,我们也可以根据接口拓展其功能,那么下面,我们就来了解一下shiro中关于Session管理的部分内容这是一个管理器实现类,是shiro提供的可用的结构。
上面两个图是该SessionManager的方法,当然,这些方法并不是全部,因为这个默认的管理器其实继承于其他的一些结构,下面是整个sessionManager的UML图
有关这部分的源码分析,我会在下次有精力的时候用一篇文章更新
获取当前subject的主机地址,该地址是通过HostAuthenticationToken.getHost()提供的。
获取/设置当前Session的过期时间;如果不设置是默认的会话管理器的全局过期时间。
获取会话的启动时间和最后访问时间;如果是JavaSE应用需要自己定期调用session.touch()去更新最后访问时间;如果是web应用,每次进入ShiroFilter都会自动调用session.touch()来更新最后访问时间。
更新会话最后访问时间及销毁会话;当Subject.logout()时会自动调用stop方法来销毁会话的。如果在web中,调用javax.servlet.http.HttpSession. invalidate()也会自动调用Shiro Session.stop方法进行销毁Shiro的会话。
设置/获取/删除会话属性;在整个会话范围内都可以对这些属性进行操作。
SessionManager负责创建和管理用户Session生命周期,在任何环境下都可以提供用户健壮的session体验。默认情况下,Shiro会使用容器自带的session机制,但若是容器不存在session,那么Shiro会提供内置的企业级session来管理。当然在开发中,也可以使用SessionDAO允许数据源持久化Session。
shiro(6)- SessionMananger(操作session)
Shiro AbstractValidatingSessionManager设计概念
AbstractValidatingSessionManager具体实现了ValidatingSessionManager的行为,覆盖AbstractNativeSessionManager的行为,定义抽象行为
具备了SessionValidationScheduler(Session校验任务调度器,set注入方式)、sessionValidationSchedulerEnabled(Session校验任务调度器开关,set注入方式,默认开启);
// 如果有必要的话开启Session校验
private void enableSessionValidationIfNecessary()
SessionValidationScheduler scheduler = getSessionValidationScheduler();
// Session校验开关开启并且Session校验任务调度器为空或者是不可用
if (isSessionValidationSchedulerEnabled() && (scheduler == null || !scheduler.isEnabled()))
// 开启Session校验
enableSessionValidation();
开启Session校验
protected synchronized void enableSessionValidation()
SessionValidationScheduler scheduler = getSessionValidationScheduler();
if (scheduler == null)
// 创建Session校验任务调度器,后文详解#1
scheduler = createSessionValidationScheduler();
// 为AbstractValidatingSessionManager设置Session校验任务调度器
setSessionValidationScheduler(scheduler);
// 可能Session校验任务调度器已经被创建只不过还没有启用
if (!scheduler.isEnabled())
if (log.isInfoEnabled())
log.info("Enabling session validation scheduler...");
// 启用Session校验任务调度器,后文详解#2
scheduler.enableSessionValidation();
// 启用Session校验任务调度器后需要做的事情
afterSessionValidationEnabled();
// 一个空的方法,等待覆盖
protected void afterSessionValidationEnabled()
书接前文#1
protected SessionValidationScheduler createSessionValidationScheduler()
ExecutorServiceSessionValidationScheduler scheduler;
if (log.isDebugEnabled())
log.debug("No sessionValidationScheduler set. Attempting to create default instance.");
// SessionValidationScheduler注入AbstractValidatingSessionManager
scheduler = new ExecutorServiceSessionValidationScheduler(this);
// 设置任务调度器的时间间隔,默认60分钟
scheduler.setInterval(getSessionValidationInterval());
if (log.isTraceEnabled())
log.trace("Created default SessionValidationScheduler instance of type [" + scheduler.getClass().getName() + "].");
return scheduler;
书接前文#2
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
private ScheduledExecutorService service;
public void enableSessionValidation()
if (this.interval > 0l)
this.service = Executors.newSingleThreadScheduledExecutor(new ThreadFactory()
private final AtomicInteger count = new AtomicInteger(1);
public Thread newThread(Runnable r)
Thread thread = new Thread(r);
thread.setDaemon(true);
thread.setName(threadNamePrefix + count.getAndIncrement());
return thread;
);
this.service.scheduleAtFixedRate(this, interval, interval, TimeUnit.MILLISECONDS);
this.enabled = true;
public void run()
if (log.isDebugEnabled())
log.debug("Executing session validation...");
long startTime = System.currentTimeMillis();
// ValidatingSessionManager执行校验Session的任务
this.sessionManager.validateSessions();
long stopTime = System.currentTimeMillis();
if (log.isDebugEnabled())
log.debug("Session validation completed successfully in " + (stopTime - startTime) + " milliseconds.");
校验所有有效的Session
public void validateSessions()
if (log.isInfoEnabled())
log.info("Validating all active sessions...");
int invalidCount = 0;
// 获得所有有效的Session,从其他介质中获得(如Redis)
Collection<Session> activeSessions = getActiveSessions();
if (activeSessions != null && !activeSessions.isEmpty())
for (Session s : activeSessions)
try
SessionKey key = new DefaultSessionKey(s.getId());
// 执行具体的校验任务
validate(s, key);
catch (InvalidSessionException e)
if (log.isDebugEnabled())
boolean expired = (e instanceof ExpiredSessionException);
String msg = "Invalidated session with id [" + s.getId() + "]" +
(expired ? " (expired)" : " (stopped)");
log.debug(msg);
invalidCount++;
if (log.isInfoEnabled())
String msg = "Finished session validation.";
if (invalidCount > 0)
msg += " [" + invalidCount + "] sessions were stopped.";
else
msg += " No sessions were stopped.";
log.info(msg);
// 空方法,AbstractValidatingSessionManager本身是没有这个职能的只能交给子类去实现,待子类覆盖
protected abstract Collection<Session> getActiveSessions();
具体的校验任务
protected void validate(Session session, SessionKey key) throws InvalidSessionException
try
// Session为基础Session:SimpleSession
doValidate(session);
catch (ExpiredSessionException ese)
onExpiration(session, ese, key);
throw ese;
catch (InvalidSessionException ise)
onInvalidation(session, ise, key);
throw ise;
protected void doValidate(Session session) throws InvalidSessionException
if (session instanceof ValidatingSession)
// 面向对象,只有Session自己能校验自己是否过期了(类似于门把自己关上了)
((ValidatingSession) session).validate();
else
String msg = "The " + getClass().getName() + " implementation only supports validating " +
"Session implementations of the " + ValidatingSession.class.getName() + " interface. " +
"Please either implement this interface in your session implementation or override the " +
AbstractValidatingSessionManager.class.getName() + ".doValidate(Session) method to perform validation.";
throw new IllegalStateException(msg);
以上是关于Shiro Session管理——操作session的主要内容,如果未能解决你的问题,请参考以下文章