spring security中ajax超时处理
程序员文章站
2022-05-08 14:17:18
...
spring security为我们的系统提供了方便的认证和授权操作。在系统中完成认证和授权后,一般页面页面上大多数是ajax和后台进行操作,那么这个时候可能就会面临session超时,ajax去访问后台的操作。或用户ajax匿名去访问一个受限的操作,此时应该如何进行处理。
面对以上可能发生的2中情况,我们可能希望进行统一的处理,将此次ajax请求导向登录界面。
1. 当用户session超时后,使用ajax进行访问 可以知道是SessionManagementFilter中的InvalidSessionStrategy进行处理的 2. 当用户是匿名用户访问,且session是新建的时候,访问了系统中的受限资源 可以知道是ExceptionTranslationFilter中的handleSpringSecurityException进行处理 handleSpringSecurityException |- 匿名用户将使用 authenticationEntryPoint 进行处理 |- 非匿名用户使用 accessDeniedHandler 进行处理
具体的处理思路如下:
1、拦截全局ajax请求
2、重写InvalidSessionStrategy,增加ajax请求的处理
3、重写AuthenticationEntryPoint增加ajax请求的处理
具体步骤:
一、拦截全局ajax请求
判断后台返回的值是否是 session-time ,如果是则直接将该请求导向登录请求
$(document).ajaxComplete(function (event, obj) { var response = obj.responseText; if (response === 'session-timeout') { location.href = ctx + '/back/forward/login'; } });二、当session超时后去,ajax请求访问后台,此时会被SessionManagementFilter进行拦截,由下图中可知,此时需要重写 InvalidSessionStrategy 类。
@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; } }注:一般ajax请求都有一个请求头X-Requeseted-With,且它的值是XMLHttpRequest
如果涉及到跨域可能没有这个请求头,那么我们可以重写ajax请求加上一个自定义的请求头,只要能判断出ajax请求即可。
三、session是新建的,用户是匿名用户,此时ajax请求是访问一个受限的方法,由下图可知,此时需要重写 AuthenticationEntryPoint 类
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); } } }四、spring secuirty 配置文件中增加这2个ajax 操作的处理