shiro安全框架扩展教程--异常退出没有清除缓存信息处理方案
2017-02-23 12:08
1171 查看
自从之前研究了security3一段时间,发现也不咋滴,后来转行去玩玩shiro,感觉还是挺不错的,小巧灵活;然后遇到个大家都应该遇到过的问题就是当用户退出或者异常关闭浏览器的时候不会自动清除缓存授权信息,当然shiro是有个玩意会自动扫描过期的会话,但是它只会清除会话信息不会清除cache里面的信息,看了网上的答案都是不靠谱的,最好还是自己看源码吧,下面看我的解决方案
[java] view
plain copy
<!-- 默认会话管理器 -->
<bean id="sessionManager"
class="com.shadow.shiro.extend.session.impl.SimpleWebSessionManager">
<property name="globalSessionTimeout" value="15000" />
<property name="sessionValidationInterval" value="30000" />
<property name="sessionValidationSchedulerEnabled" value="true" />
</bean>
全局的会话信息设置成15秒,检测扫描信息间隔30秒,第三个参数就是是否开启扫描
至于我的sessionManager实现类是自己继承,然后重写了其中一个方法
[java] view
plain copy
package com.shadow.shiro.extend.session.impl;
import java.util.Collection;
import java.util.Iterator;
import org.apache.log4j.Logger;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.session.ExpiredSessionException;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.DefaultSessionKey;
import org.apache.shiro.session.mgt.SessionKey;
import org.apache.shiro.session.mgt.SimpleSession;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import com.shadow.shiro.extend.session.WebSessionManager;
/**
* 会话管理器
*
* @author shadow
*
*/
public class SimpleWebSessionManager extends DefaultWebSessionManager implements
WebSessionManager {
private CacheManager cacheManager;
private final static Logger logger = Logger
.getLogger(SimpleWebSessionManager.class);
public SimpleWebSessionManager() {
super();
}
public void validateSessions() {
if (logger.isInfoEnabled())
logger.info("Validating all active sessions...");
int invalidCount = 0;
Collection<?> activeSessions = getActiveSessions();
if (activeSessions != null && !activeSessions.isEmpty()) {
for (Iterator<?> i$ = activeSessions.iterator(); i$.hasNext();) {
Session session = (Session) i$.next();
try {
SessionKey key = new DefaultSessionKey(session.getId());
validate(session, key);
} catch (InvalidSessionException e) {
if (cacheManager != null) {
SimpleSession s = (SimpleSession) session;
if (s.getAttribute(SESSION_USER_KEY) != null)
cacheManager.getCache(null).remove(
s.getAttribute(SESSION_USER_KEY));
}
if (logger.isDebugEnabled()) {
boolean expired = e instanceof ExpiredSessionException;
String msg = (new StringBuilder()).append(
"Invalidated session with id [").append(
session.getId()).append("]").append(
expired ? " (expired)" : " (stopped)")
.toString();
logger.debug(msg);
}
invalidCount++;
}
}
}
if (logger.isInfoEnabled()) {
String msg = "Finished session validation.";
if (invalidCount > 0)
msg = (new StringBuilder()).append(msg).append(" [").append(
invalidCount).append("] sessions were stopped.")
.toString();
else
msg = (new StringBuilder()).append(msg).append(
" No sessions were stopped.").toString();
logger.info(msg);
}
}
public void setCacheManager(CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
}
其中这里的方法是校验会话的,我在方法上加入了cachemanager的接口,然后重写set方法,就能获得实例,然后在执行期间调用cache.remove()方法,就能清空缓存上的信息了;
[java] view
plain copy
<!-- 默认会话管理器 -->
<bean id="sessionManager"
class="com.shadow.shiro.extend.session.impl.SimpleWebSessionManager">
<property name="globalSessionTimeout" value="15000" />
<property name="sessionValidationInterval" value="30000" />
<property name="sessionValidationSchedulerEnabled" value="true" />
</bean>
全局的会话信息设置成15秒,检测扫描信息间隔30秒,第三个参数就是是否开启扫描
至于我的sessionManager实现类是自己继承,然后重写了其中一个方法
[java] view
plain copy
package com.shadow.shiro.extend.session.impl;
import java.util.Collection;
import java.util.Iterator;
import org.apache.log4j.Logger;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.session.ExpiredSessionException;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.DefaultSessionKey;
import org.apache.shiro.session.mgt.SessionKey;
import org.apache.shiro.session.mgt.SimpleSession;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import com.shadow.shiro.extend.session.WebSessionManager;
/**
* 会话管理器
*
* @author shadow
*
*/
public class SimpleWebSessionManager extends DefaultWebSessionManager implements
WebSessionManager {
private CacheManager cacheManager;
private final static Logger logger = Logger
.getLogger(SimpleWebSessionManager.class);
public SimpleWebSessionManager() {
super();
}
public void validateSessions() {
if (logger.isInfoEnabled())
logger.info("Validating all active sessions...");
int invalidCount = 0;
Collection<?> activeSessions = getActiveSessions();
if (activeSessions != null && !activeSessions.isEmpty()) {
for (Iterator<?> i$ = activeSessions.iterator(); i$.hasNext();) {
Session session = (Session) i$.next();
try {
SessionKey key = new DefaultSessionKey(session.getId());
validate(session, key);
} catch (InvalidSessionException e) {
if (cacheManager != null) {
SimpleSession s = (SimpleSession) session;
if (s.getAttribute(SESSION_USER_KEY) != null)
cacheManager.getCache(null).remove(
s.getAttribute(SESSION_USER_KEY));
}
if (logger.isDebugEnabled()) {
boolean expired = e instanceof ExpiredSessionException;
String msg = (new StringBuilder()).append(
"Invalidated session with id [").append(
session.getId()).append("]").append(
expired ? " (expired)" : " (stopped)")
.toString();
logger.debug(msg);
}
invalidCount++;
}
}
}
if (logger.isInfoEnabled()) {
String msg = "Finished session validation.";
if (invalidCount > 0)
msg = (new StringBuilder()).append(msg).append(" [").append(
invalidCount).append("] sessions were stopped.")
.toString();
else
msg = (new StringBuilder()).append(msg).append(
" No sessions were stopped.").toString();
logger.info(msg);
}
}
public void setCacheManager(CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
}
其中这里的方法是校验会话的,我在方法上加入了cachemanager的接口,然后重写set方法,就能获得实例,然后在执行期间调用cache.remove()方法,就能清空缓存上的信息了;
相关文章推荐
- shiro安全框架扩展教程--异常退出没有清除缓存信息处理方案
- shiro安全框架扩展教程--异常退出没有清除缓存信息处理方案
- shiro安全框架异常退出没有清除缓存信息处理方案
- shiro安全框架扩展教程--如何扩展realm桥接器并退出自动清空角色资源缓存
- shiro安全框架扩展教程--如何扩展实现我们的缓存机制(第三方容器redis,memcached)
- shiro安全框架扩展教程--如何扩展实现我们的缓存机制(第三方容器redis,memcached)
- shiro安全框架扩展教程--如何扩展实现我们的缓存机制(第三方容器redis,memcached)
- shiro安全框架扩展教程--如何自定义适合项目的过滤器
- shiro安全框架扩展教程--如何动态控制页面节点元素的权限
- shiro安全框架扩展教程--如何扩展实现集中式session管理(redis,memcached等)
- shiro安全框架扩展教程--整合cas框架扩展自定义CasRealm
- shiro安全框架扩展教程--如何扩展异步(ajax)请求认证失败处理
- shiro安全框架扩展教程--如何扩展异步(ajax)请求认证失败处理
- shiro安全框架扩展教程--如何防止可执行文件的入侵攻击【转】
- shiro安全框架扩展教程--如何防止可执行文件的入侵攻击
- shiro安全框架扩展教程--角色树控制展示(ztree框架)
- shiro安全框架扩展教程--上传文件的安全控制
- shiro安全框架扩展教程--验证码的安全(jcaptcha框架)
- shiro安全框架扩展教程--如何动态控制页面节点元素的权限
- 用EhCache缓存Shiro的本地会话,当用户没有安全退出就直接关闭浏览器,会话可能在缓存里孤立的问题。