Spring Security is a Security framework that provides declarative secure access control solutions for Spring-based enterprise applications. It provides a set of beans that can be configured in a Spring application context, taking full advantage of Spring IoC,DI (Inversion of Control), and AOP (aspect oriented programming) capabilities. Provide declarative secure access control function for application system, reduce the work of writing a lot of repetitive code for enterprise system security control.

Exit the principle

  1. removeCookie
  2. Clears the current user’sremember-merecord
  3. Make the currentsessionfailure
  4. Clear the currentSecurityContext
  5. Redirect to the login screen

Spring Security’s exit request (which defaults to /logout) is intercepted by the LogoutFilter filter.

Implementation of exit

  1. Add an exit link to the home page
<a href="/signOut">exit</a>
Copy the code
  1. Configuration MerryyouSecurityConfig
. .and() .logout() .logoutUrl("/signOut")// Define the exit address
                .logoutSuccessUrl("/register")// Go to the registration page after exit
                .deleteCookies("JSESSIONID")// Delete the current JSESSIONID
                .and()
......
Copy the code

Results the following

https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/1/18/16108afa77d2051e~tplv-t2oaga2asx-image.image

Source code analysis

LogoutFilter#doFilter

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;
		//#1. Matches the /logout request
		if (requiresLogout(request, response)) {
			Authentication auth = SecurityContextHolder.getContext().getAuthentication();

			if (logger.isDebugEnabled()) {
				logger.debug("Logging out user '" + auth
						+ "' and transferring to logout destination");
			}
			//#2. Handle steps 1-4
			this.handler.logout(request, response, auth);
			//#3. Redirect to the registration screen
			logoutSuccessHandler.onLogoutSuccess(request, response, auth);

			return;
		}

		chain.doFilter(request, response);
	}
Copy the code
  1. Matches the currently intercepted request
  2. Processing to emptyCookie,remember-me,sessionandSecurityContext
  3. Redirect to the login screen

handler

https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/1/18/16108afa7517f33a~tplv-t2oaga2asx-image.image

  1. CookieClearingLogoutHandleremptyCookie
  2. PersistentTokenBasedRememberMeServicesemptyremember-me
  3. SecurityContextLogoutHandlerMake the currentsessionVoid, empty currentSecurityContext
CookieClearingLogoutHandler#logout
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
		for (String cookieName : cookiesToClear) {
			//# 1. Set Cookie to null
			Cookie cookie = new Cookie(cookieName, null);
			String cookiePath = request.getContextPath();
			if(! StringUtils.hasLength(cookiePath)) { cookiePath ="/";
			}
			cookie.setPath(cookiePath);
			cookie.setMaxAge(0); response.addCookie(cookie); }}Copy the code
  1. CookieSet to null

PersistentTokenBasedRememberMeServices#logout

public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
		super.logout(request, response, authentication);

		if(authentication ! =null) {
			// clear the persistent_logins tabletokenRepository.removeUserTokens(authentication.getName()); }}Copy the code
  1. Clear records in the persistent_logins table

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());
				//#1. Invalidate the current sessionsession.invalidate(); }}if (clearAuthentication) {
			SecurityContext context = SecurityContextHolder.getContext();
			Empty the current 'SecurityContext'
			context.setAuthentication(null);
		}

		SecurityContextHolder.clearContext();
	}
Copy the code
  1. Invalidates the current session
  2. Clear the currentSecurityContext

AbstractAuthenticationTargetUrlRequestHandler#handle

	protected void handle(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
		//#1
		String targetUrl = determineTargetUrl(request, response);

		if (response.isCommitted()) {
			logger.debug("Response has already been committed. Unable to redirect to "
					+ targetUrl);
			return;
		}
		//#2
		redirectStrategy.sendRedirect(request, response, targetUrl);
	}
Copy the code
  1. Gets the configured forward address
  2. A jump request

The code download

Download it from my Github, github.com/longfeizhen…