解决spring boot shiro的logout过滤器任何请求都会调用的问题

2023-04-10 16:19:59

最近发现了一个问题,我写了一个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,也按照这个例子再新增一个就行了

  • 作者:雾里看花の
  • 原文链接:https://blog.csdn.net/genaro26/article/details/91444469
    更新时间:2023-04-10 16:19:59