/** * Copyright © 2015-2020 JeePlus All rights reserved. */ package com.jeeplus.common.security.shiro.session; import java.io.Serializable; import java.util.Collection; import java.util.Set; import javax.servlet.http.HttpServletRequest; import org.apache.shiro.session.Session; import org.apache.shiro.session.UnknownSessionException; import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.subject.support.DefaultSubjectContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.collect.Sets; import com.jeeplus.common.config.Global; import com.jeeplus.common.utils.DateUtils; import com.jeeplus.common.utils.StringUtils; import com.jeeplus.common.web.Servlets; /** * 系统安全认证实现类 * @author jeeplus * @version 2014-7-24 */ public class CacheSessionDAO extends EnterpriseCacheSessionDAO implements SessionDAO { private Logger logger = LoggerFactory.getLogger(getClass()); public CacheSessionDAO() { super(); } @Override protected void doUpdate(Session session) { if (session == null || session.getId() == null) { return; } HttpServletRequest request = Servlets.getRequest(); if (request != null){ String uri = request.getServletPath(); // 如果是静态文件,则不更新SESSION if (Servlets.isStaticFile(uri)){ return; } // 如果是视图文件,则不更新SESSION if (StringUtils.startsWith(uri, Global.getConfig("web.view.prefix")) && StringUtils.endsWith(uri, Global.getConfig("web.view.suffix"))){ return; } // 手动控制不更新SESSION String updateSession = request.getParameter("updateSession"); if (Global.FALSE.equals(updateSession) || Global.NO.equals(updateSession)){ return; } } super.doUpdate(session); logger.debug("update {} {}", session.getId(), request != null ? request.getRequestURI() : ""); } @Override protected void doDelete(Session session) { if (session == null || session.getId() == null) { return; } super.doDelete(session); logger.debug("delete {} ", session.getId()); } @Override protected Serializable doCreate(Session session) { HttpServletRequest request = Servlets.getRequest(); if (request != null){ String uri = request.getServletPath(); // 如果是静态文件,则不创建SESSION if (Servlets.isStaticFile(uri)){ return null; } } super.doCreate(session); logger.debug("doCreate {} {}", session, request != null ? request.getRequestURI() : ""); return session.getId(); } @Override protected Session doReadSession(Serializable sessionId) { return super.doReadSession(sessionId); } @Override public Session readSession(Serializable sessionId) throws UnknownSessionException { try{ Session s = null; HttpServletRequest request = Servlets.getRequest(); if (request != null){ String uri = request.getServletPath(); // 如果是静态文件,则不获取SESSION if (Servlets.isStaticFile(uri)){ return null; } s = (Session)request.getAttribute("session_"+sessionId); } if (s != null){ return s; } Session session = super.readSession(sessionId); logger.debug("readSession {} {}", sessionId, request != null ? request.getRequestURI() : ""); if (request != null && session != null){ request.setAttribute("session_"+sessionId, session); } return session; }catch (UnknownSessionException e) { return null; } } /** * 获取活动会话 * @param includeLeave 是否包括离线(最后访问时间大于3分钟为离线会话) * @return */ @Override public Collection getActiveSessions(boolean includeLeave) { return getActiveSessions(includeLeave, null, null); } /** * 获取活动会话 * @param includeLeave 是否包括离线(最后访问时间大于3分钟为离线会话) * @param principal 根据登录者对象获取活动会话 * @param filterSession 不为空,则过滤掉(不包含)这个会话。 * @return */ @Override public Collection getActiveSessions(boolean includeLeave, Object principal, Session filterSession) { // 如果包括离线,并无登录者条件。 if (includeLeave && principal == null){ return getActiveSessions(); } Set sessions = Sets.newHashSet(); for (Session session : getActiveSessions()){ boolean isActiveSession = false; // 不包括离线并符合最后访问时间小于等于3分钟条件。 if (includeLeave || DateUtils.pastMinutes(session.getLastAccessTime()) <= 3){ isActiveSession = true; } // 符合登陆者条件。 if (principal != null){ PrincipalCollection pc = (PrincipalCollection)session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY); if (principal.toString().equals(pc != null ? pc.getPrimaryPrincipal().toString() : StringUtils.EMPTY)){ isActiveSession = true; } } // 过滤掉的SESSION if (filterSession != null && filterSession.getId().equals(session.getId())){ isActiveSession = false; } if (isActiveSession){ sessions.add(session); } } return sessions; } }