最近发现了一个问题,我写了一个shiro logout过滤器,本意是在退出登录时清空一些缓存,如下:
public class CustomLogoutFilter extends LogoutFilter{
private static String checkOutFlag = "checkOut";
private Cache<String, Deque<Serializable>> cache;
public void setCacheManager(CacheManager cacheManager) {
this.cache = cacheManager.getCache("shiro_redis_cache");
}
@Override
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
System.out.println("开始过滤...");
// 清空相关缓存
Subject subject = getSubject(request, response);
if(subject != null && subject.getPrincipal() != null) {
Session session = subject.getSession();
LoginBean loginBean = (LoginBean) subject.getPrincipal();
String staffNo = loginBean.getStaffNo();
Serializable sessionId = session.getId();
Deque<Serializable> deque = cache.get(staffNo);
if(deque != null && deque.contains(sessionId)) {
//清除为了校验单一登录留下的缓存
deque.remove(sessionId);
if(deque.size() == 0) {
cache.remove(staffNo);
} else {
cache.put(staffNo, deque);
}
session.setAttribute(checkOutFlag, null);
}
}
String redirectUrl = getRedirectUrl(request, response, subject);
try {
subject.logout();
} catch (SessionException ise) {
ise.printStackTrace();
}
issueRedirect(request, response, redirectUrl);
return false;
}
}
然后奇怪的事情发生了,网页都进不去,提示重定向次数过多,debug发现每一次的请求都会进入logout拦截器,这显然是不对的,查看spring boot的相关文档(点我进入spring boot文档网页)发现有如下说明:
大概意思是:任何Servlet或Filter bean都将自动注册到servlet容器中。要禁用特定Filter或Servlet bean的注册,请为其创建注册bean并将其标记为禁用。
问题就出在这里,我写的logout过滤器被spring boot自动注册到servlet容器中了,本来是要由shiro去管理这个filter的,现在却变成spring boot管理了,要解决这个问题,只需要按照文档所说的做就行了
@Configuration
public class ShiroFilterRegisterConfig {
/**
* @desc 方法名字可以随便取
* @param filter
* @return
*/
@Bean
public FilterRegistrationBean<CheckSessionControlFilter> shiroCheckSessionRegistration(CheckSessionControlFilter filter) {
FilterRegistrationBean<CheckSessionControlFilter> registration = new FilterRegistrationBean<CheckSessionControlFilter>(filter);
registration.setEnabled(false);
return registration;
}
}
如果你还有其他的filter,也按照这个例子再新增一个就行了