Spring Security学习笔记之LogoutFilter

处理logout方法比较简单, 只需要在标签里配置标签即可:


	...
	
	...
这里配置了当logout成功后跳转到login页面.


也可以指定自定义的LogoutSuccessHandler, 在logout成功后做一些其他操作, 如记录日志, 更新数据库等等.


	...
	
	...


这里注意两点:

1) 标签里的logout-success-url和success-handler-ref只能指定其中一个, 不能两个都指定.

2) 自定义的LogoutHandler一定要实现LogoutSuccessHandler接口. logout成功后的具体操作写在onLogoutSuccess()方法里.


那么Spring Security是怎么处理logout操作的呢?

Spring Security把logout操作交给了LogoutFilter处理.

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
		throws IOException, ServletException {
	HttpServletRequest request = (HttpServletRequest) req;
	HttpServletResponse response = (HttpServletResponse) res;

	if (requiresLogout(request, response)) {
		Authentication auth = SecurityContextHolder.getContext().getAuthentication();

		if (logger.isDebugEnabled()) {
			logger.debug("Logging out user '" + auth + "' and transferring to logout destination");
		}

		// 此处的handler是一个SecurityContextLogoutHandler的实例
		for (LogoutHandler handler : handlers) {
			handler.logout(request, response, auth);
		}

		// logoutSuccessHandler就是在标签里指定的自定义handler
		logoutSuccessHandler.onLogoutSuccess(request, response, auth);

		return;
	}

	chain.doFilter(request, response);
}

可以看到LogoutFilter首先把请求交给SecurityContextLogoutHandler来处理, 而SecurityContextLogoutHandler只做了两件事, 1) 把当前session无效化, 2) 从SecurityContext里注销当前授权用户.

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();
}

然后再交给我们自定义的logoutSuccessHandler来处理.


你可能感兴趣的:(Spring Security学习笔记之LogoutFilter)