更详细看原文 https://my.oschina.net/u/729917/blog/885421
在ajax请求时,如果session失效时,无法正确的跳转登录页面。在之前的项目中处理的方法是通过自定义一个过滤器来处理,session失效时返回错误码来处理。但因为使用shiro后,会先执行shiro定义的过滤器,才会执行自定义的过滤器,所以之前的方法行不通,参考了很多大大的博客,把我的处理方法贴上。
1.自定义拦截器LoginFormFilter拦截器,继承FormAuthenticationFilter类,在需要登录而未登录的请求都会执行onAccessDenied请求。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
package com.xxfy.demo.filter; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.shiro.web.filter.authc.FormAuthenticationFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.xxfy.demo.util.HttpUtils; public class LoginFormFilter extends FormAuthenticationFilter { private static final Logger log = LoggerFactory.getLogger(LoginFormFilter.class); @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { HttpServletRequest httpServletRequest = (HttpServletRequest)request; HttpServletResponse httpServletResponse = (HttpServletResponse)response; if (isLoginRequest(request, response)) { if (isLoginSubmission(request, response)) { if (log.isTraceEnabled()) { log.trace("Login submission detected. Attempting to execute login."); } return executeLogin(request, response); } else { if (log.isTraceEnabled()) { log.trace("Login page view."); } //allow them to see the login page ;) return true; } } else { if (log.isTraceEnabled()) { log.trace("Attempting to access a path which requires authentication. Forwarding to the " + "Authentication url [" + getLoginUrl() + "]"); } //如果是Ajax请求,不跳转登录 if (HttpUtils.isAjax(httpServletRequest)){ System.out.println("ajax"); httpServletResponse.setStatus(401); } else { saveRequestAndRedirectToLogin(request, response); } return false; } } } |
此处的onAccessDenied方法跟FormAuthenticationFilter基本类似,只是加了一段判断是ajax请求的代码 ,如果是ajax请求的话,直接返回错误码,而不是跳转登录,因为如果是ajax请求的话,也无法跳转。