思路:
用户登录信息存放缓存ehCache,调用登录接口之前,从缓存获取系统当前在线用户数据,数据包含sessionId和账号。如果当前登录账号和获取的在线用户的账号相同,则把这个账号的sessionId的timeout设置为1秒。
1. 配置EhCache
将EhCache与SpringBoot整合在一起,这其中就要装配两个重要的bean[EhCacheManagerFactoryBean]和[EhCacheManager]
@Configuration
public class ShiroConfiguration {
public ShiroConfiguration() {
}
//配置缓存信息ehcach.xml
@Bean(name = {"ehCacheManagerFactoryBean"})
public EhCacheManagerFactoryBean ehCacheManagerFactoryBean() {
EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean();
ClassPathResource classPathResource = new ClassPathResource("cache/ehcache-local.xml");
ehCacheManagerFactoryBean.setConfigLocation(classPathResource);
return ehCacheManagerFactoryBean;
}
//缓存管理器
@Bean(name = {"shiroCacheManager"})
public EhCacheManager shiroCacheManager() {
EhCacheManager ehCacheManager = new EhCacheManager();
ehCacheManager.setCacheManager(this.ehCacheManagerFactoryBean.getObject());
return ehCacheManager;
}
@Bean(name = {"securityManager"})
public SecurityManager securityManager() {
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
//授权域。继承AuthorizingRealm重写doGetAuthenticationInfo认证、doGetAuthorizationInfo授权
defaultWebSecurityManager.setRealm(*****);
defaultWebSecurityManager.setSessionManager(this.getDefaultWebSessionManager());
defaultWebSecurityManager.setCacheManager(this.shiroCacheManager());
SecurityUtils.setSecurityManager(defaultWebSecurityManager);
return defaultWebSecurityManager;
}
@Bean(name = {"defaultWebSessionManager"})
public DefaultWebSessionManager getDefaultWebSessionManager() {
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
sessionManager.setGlobalSessionTimeout(3600000L);
sessionManager.setDeleteInvalidSessions(true);
sessionManager.setSessionValidationSchedulerEnabled(true);
sessionManager.setDeleteInvalidSessions(true);
sessionManager.setSessionIdCookieEnabled(true);
sessionManager.setSessionDAO(this.sessionDao());
sessionManager.setCacheManager(this.shiroCacheManager());
return sessionManager;
}
@Bean(name = {"sessionDao"})
public EnterpriseCacheSessionDAO sessionDao() {
EnterpriseCacheSessionDAO sessionDao = new EnterpriseCacheSessionDAO();
//存放session的ehcache名称
sessionDao.setActiveSessionsCacheName("shiro-activeSessionCache");
//sessionId生成规则,查看源码实际上就是UUID.randomUUID().toString()
sessionDao.setSessionIdGenerator(new JavaUuidSessionIdGenerator());
return sessionDao;
}
}
2. 调用登录接口前获取当前在线用户信息
public OnlineUserVO getOnlineUser() {
Set userIdSet = new HashSet();
OnlineUserVO onlineUserVO = new OnlineUserVO();
List onlineUserEOList = new ArrayList();
//获取当前所有活跃用户
Collection sessions = this.sessionDAO.getActiveSessions();
Iterator var5 = sessions.iterator();
while(var5.hasNext()) {
Object sessionObject = var5.next();
if (sessionObject instanceof SimpleSession) {
SimpleSession simpleSession = (SimpleSession)sessionObject;
Object object = simpleSession.getAttribute("LOGIN_USER");
if (null != object) {
UserEO userEO = (UserEO)object;
if (!userIdSet.add(userEO.getUsid())) {
break;
}
OnlineUserEO onlineUserEO = new OnlineUserEO();
onlineUserEO.setAccount(userEO.getAccount());
onlineUserEO.setIp(simpleSession.getHost());
onlineUserEO.setLoginTime(simpleSession.getStartTimestamp());
onlineUserEO.setSessionId(simpleSession.getId().toString());
onlineUserEOList.add(onlineUserEO);
}
}
}
onlineUserVO.setOnlineUsers(onlineUserEOList);
onlineUserVO.setTotal(onlineUserEOList.size());
return onlineUserVO;
}
在第一步配置EhCache信息时,sessionDao方法配置了缓存名称sessionDao.setActiveSessionsCacheName("shiro-activeSessionCache");
返回的数据包含sessionId
3. 用huihua
public void loginOutBySessionId(String sessionId) {
Collection sessions = this.sessionDAO.getActiveSessions();
Iterator var3 = sessions.iterator();
while(var3.hasNext()) {
Object sessionObject = var3.next();
if (sessionObject instanceof SimpleSession) {
SimpleSession simpleSession = (SimpleSession)sessionObject;
if (StringUtils.equals(sessionId, simpleSession.getId().toString())) {
simpleSession.setTimeout(1000L);
}
}
}
}
需要下线的账号的sessionId的会话时间设置为1000毫秒。
4. 登录信息存放到ehCache缓存
//只展示核心内容
public Message login(HttpServletRequest request, UsernamePasswordToken token) {
Subject subject = SecurityUtils.getSubject();
//登录
subject.login(token);
Session session = subject.getSession(true);
//获取当前登录用户信息
UserEO userEO = UserUtils.getUser();
session.setAttribute("LOGIN_USER", userEO);
//获取用户的角色
UserEO returnEO = this.userService.getRoles(userEO.getUsid());
session.setAttribute("LOGIN_USER_ID", userEO.getUsid());
session.setAttribute("LOGIN_ROLE_ID", UserUtils.getRoleIds());
//把session信息存放ehcache
if (null != session) {
CacheUtils.putShiroSessionCache(userEO.getUsid(), session.getId());
}
}
//获取当前登录用户信息
public static UserEO getUser() {
//缓存获取用户信息
UserEO user = (UserEO)CacheUtils.getCache("currentUser");
if (user == null) {
String userId = null;
Subject subject = SecurityUtils.getSubject();
MyPrincipal principal = (MyPrincipal)subject.getPrincipal();
if (principal != null) {
userId = principal.getId();
}
if (StringUtils.isNotEmpty(userId)) {
//查询用户信息
user = userService.getUser(userId);
user.setPassword((String)null);
//用户信息放缓存
CacheUtils.putCache("currentUser", user);
}
}
return user;
}
public class CacheUtils {
public static void putShiroSessionCache(String key, Object value) {
Element element = new Element(key, value);
String cacheName = "shiro-activeSessionCache";
Cache cache = cacheManager.getCache(cacheName);
if (cache == null) {
cacheManager.addCache(cacheName);
cache = cacheManager.getCache(cacheName);
cache.getCacheConfiguration().setEternal(true);
}
cache.put(element);
}
public static Object getCache(String key, Object defaultValue) {
Object obj = getCacheMap().get(key);
return obj == null ? defaultValue : obj;
}
//
public static void putCache(String key, Object value) {
getCacheMap().put(key, value);
}
public static Map getCacheMap() {
HashMap map = Maps.newHashMap();
try {
Subject subject = SecurityUtils.getSubject();
//MyPrincipal信息来源于realm中doGetAuthenticationInfo的new SimpleAuthenticationInfo()
MyPrincipal principal = (MyPrincipal)subject.getPrincipal();
return (Map)(principal != null ? principal.getCacheMap() : map);
} catch (UnavailableSecurityManagerException var3) {
UserUtils.logger.error("getCacheMap UnavailableSecurityManagerException", var3);
} catch (InvalidSessionException var4) {
UserUtils.logger.error("getCacheMap InvalidSessionException", var4);
}
return map;
}
}



