SpringSecurity过滤器之LogoutFilter

shigongp / 2023-05-03 / 原文

LogoutFilter用于注销登录。

private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
		throws IOException, ServletException {
	if (requiresLogout(request, response)) {
		Authentication auth = SecurityContextHolder.getContext().getAuthentication();
		if (this.logger.isDebugEnabled()) {
			this.logger.debug(LogMessage.format("Logging out [%s]", auth));
		}
		this.handler.logout(request, response, auth);
		this.logoutSuccessHandler.onLogoutSuccess(request, response, auth);
		return;
	}
	chain.doFilter(request, response);
}

requiresLogout判断是否是注销登录请求(请求路径是否是/logout)。若是handler.logout注销登录,logoutSuccessHandler.onLogoutSuccess是注销成功后的处理(默认重定向到/login?logout)。handle是CompositeLogoutHandler。

 
CompositeLogoutHandler#logout

public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
	for (LogoutHandler handler : this.logoutHandlers) {
		handler.logout(request, response, authentication);
	}
}

logoutHandlers默认有CsrfLogoutHandler,SecurityContextLogoutHandler,LogoutSuccessEventPublishingLogoutHandler。

CsrfLogoutHandler

public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
	this.csrfTokenRepository.saveToken(null, request, response);
}

将csrf_token置为null。

SecurityContextLogoutHandler

public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
	Assert.notNull(request, "HttpServletRequest required");
	if (this.invalidateHttpSession) {
		HttpSession session = request.getSession(false);
		if (session != null) {
			session.invalidate();
			if (this.logger.isDebugEnabled()) {
				this.logger.debug(LogMessage.format("Invalidated session %s", session.getId()));
			}
		}
	}
	SecurityContext context = SecurityContextHolder.getContext();
	SecurityContextHolder.clearContext();
	if (this.clearAuthentication) {
		context.setAuthentication(null);
	}
}

将Session置为无效。清空SecurityContextHolder。

LogoutSuccessEventPublishingLogoutHandler

public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
	if (this.eventPublisher == null) {
		return;
	}
	if (authentication == null) {
		return;
	}
	this.eventPublisher.publishEvent(new LogoutSuccessEvent(authentication));
}

发布LogoutSuccessEvent事件。