LogoutFilter

扶醉桌前 提交于 2020-03-12 08:27:13

LogoutFilter

介绍

LogoutFilter是一个登出过滤器,当请求经过LogoutFilter时,过滤器会请判断当前请求的URL是否是登出URL,如果匹配,就执行遍历执行登出handlers。默认情况下,会清空SecurityContextHolder的身份认证信息,以及发送一个登出成功的事件。

代码分析

我们首先看一下LogoutFilter的构造器,代码如下:

public LogoutFilter(LogoutSuccessHandler logoutSuccessHandler,
        LogoutHandler... handlers) {
    this.handler = new CompositeLogoutHandler(handlers);
    Assert.notNull(logoutSuccessHandler, "logoutSuccessHandler cannot be null");
    this.logoutSuccessHandler = logoutSuccessHandler;
    //默认登出URL是/logout
    setFilterProcessesUrl("/logout");
}

如果我们项目的登出URL与默认登录URL有出入,需要手动配置进行配置,配置如下:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.logout().logoutUrl("/oauth2/token/remove");
}

我们看一下doFilter()方法,关键代码进行了注释,如下:

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
        throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;
	//判断是否需要进行登出操作,里边主要进行了一次URL匹配操作
    if (requiresLogout(request, response)) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        //这是一个复合的handler, 这个handler里维护一个handler list,遍历执行每一个handler的logout
        this.handler.logout(request, response, auth);
        //默认情况下,它是一个SimpleUrlLogoutSuccessHandler,重定向的/login?logout
        logoutSuccessHandler.onLogoutSuccess(request, response, auth);
        return;
    }
   
    chain.doFilter(request, response);
}

this.handler是一个复合的handler,其包含的handler如下:
image.png

SecurityContextLogoutHandler#logout如下:

public void logout(HttpServletRequest request, HttpServletResponse response,
        Authentication authentication) {
    Assert.notNull(request, "HttpServletRequest required");
    if (invalidateHttpSession) {
        HttpSession session = request.getSession(false);
        if (session != null) {
            logger.debug("Invalidating session: " + session.getId());
            session.invalidate();
        }
    }

    if (clearAuthentication) {
        SecurityContext context = SecurityContextHolder.getContext();
        //清空身份认证信息
        context.setAuthentication(null);
    }
	//清空上下文信息
    SecurityContextHolder.clearContext();
}

LogoutSuccessEventPublishingLogoutHandler#logout如下:

public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
    if (eventPublisher == null) {
        return;
    }
    if (authentication == null) {
        return;
    }
    //发送一个Spring事件
    eventPublisher.publishEvent(new LogoutSuccessEvent(authentication));
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!