Ajax timeout processing in spring security

   Spring security provides convenient authentication and authorization operations for our system. After completing the authentication and authorization in the system, most of the pages on the general page are operated by ajax and the background, then this time may face session timeout, ajax to access the background operation. Or user ajax anonymously to access a restricted operation, what should be done at this time.

   In the face of the above 2 situations that may occur, we may wish to carry out unified processing and direct this ajax request to the login interface.

1. When the user session times out, use ajax to access it.
    It can be known that it is processed
 by InvalidSessionStrategy in SessionManagementFilter . 2. When the user is an anonymous user and the session is newly created, the restricted resources in the system are accessed.
    It can be known that it is ExceptionTranslationFilter handleSpringSecurityException in
 handleSpringSecurityException _
        |- Anonymous users will be handled
 with authenticationEntryPoint |- Non-anonymous users will be handled with accessDeniedHandler
The specific processing ideas are as follows:
    1. Intercept global ajax requests
    2. Rewrite InvalidSessionStrategy and increase the processing of ajax requests
    3. Rewrite AuthenticationEntryPoint to increase the processing of ajax requests
Specific steps:
1. Intercept global ajax requests
       Determine whether the value returned by the background is  session-time , and if so, direct the request to the login request
$(document).ajaxComplete(function (event, obj) {
    var response = obj.responseText;
    if (response === 'session-timeout') {
        location.href = ctx + '/back/forward/login';
    }
});
2. When the session times out, the ajax request to access the background will be intercepted by the SessionManagementFilter. As can be seen from the figure below, the InvalidSessionStrategy class needs to be rewritten at this time.

 
@ Slf4j
public class SimpleAjaxAndRedirectInvalidSessionStrategy implements InvalidSessionStrategy {

	private final String destinationUrl;
	private final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
	private boolean createNewSession = true;

	public SimpleAjaxAndRedirectInvalidSessionStrategy(String invalidSessionUrl) {
		Assert.isTrue(UrlUtils.isValidRedirectUrl(invalidSessionUrl), "url must start with '/' or with 'http(s)'");
		this.destinationUrl = invalidSessionUrl;
	}

	@Override
	public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		if (Objects.equals(request.getHeader("X-Requested-With"), "XMLHttpRequest")) {
			response.setContentType("text/html;charset=utf-8");
			response.setCharacterEncoding("utf-8");
			response.getWriter().write("session-timeout");
			response.getWriter().close();
		} else {
			log.debug("Starting new session (if required) and redirecting to '" + destinationUrl + "'");
			if (createNewSession) {
				request.getSession();
			}
			redirectStrategy.sendRedirect(request, response, destinationUrl);
		}
	}

	/**
	 * Determines whether a new session should be created before redirecting (to avoid
	 * possible looping issues where the same session ID is sent with the redirected
	 * request). Alternatively, ensure that the configured URL does not pass through the
	 * {@code SessionManagementFilter}.
	 *
	 * @param createNewSession defaults to {@code true}.
	 */
	public void setCreateNewSession(boolean createNewSession) {
		this.createNewSession = createNewSession;
	}
}
  Note: General ajax requests have a request header X-Requested-With, and its value is XMLHttpRequest
       If there is no such request header involved in cross-domain, then we can rewrite the ajax request and add a custom request header, as long as the ajax request can be judged.
3. The session is newly created and the user is an anonymous user. At this time, the ajax request is to access a restricted method . As can be seen from the following figure, the AuthenticationEntryPoint class needs to be rewritten at this time .

public class HandleAnonyAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {

	/**
	 * @param loginFormUrl URL where the login page can be found. Should either be
	 *                     relative to the web-app context path (include a leading {@code /}) or an absolute
	 *                     URL.
	 */
	public HandleAnonyAuthenticationEntryPoint(String loginFormUrl) {
		super(loginFormUrl);
	}

	@Override
	public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
		if (Objects.equals(request.getHeader("X-Requested-With"), "XMLHttpRequest")) {
			response.setContentType("text/html;charset=utf-8");
			response.setCharacterEncoding("utf-8");
			response.getWriter().write("session-timeout");
			response.getWriter().close();
		} else {
			super.commence(request, response, authException);
		}
	}
}
  Fourth, add the processing of these two ajax operations to the spring secuirty configuration file

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326301779&siteId=291194637