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如下:
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));
}
来源:CSDN
作者:小菜菜咿呀
链接:https://blog.csdn.net/liuyanglglg/article/details/104803860