本问题解决方案参照网站多篇文章融合解决,在此表示感谢!
环境:springboot+shiro+jquery-easyui
问题:在ajax请求时,如果此时session已经失效,系统没有自动跳转到登录页面。后来在服务端加了判断ajax请求的代码,结果还是没有用,无法取到ajax特定的head值(X-Requested-With)。发现jquery-easyui表单提交时没有就没有传递这个值。
解决办法:
1.添加拦截器
importjavax.servlet.ServletRequest;importjavax.servlet.ServletResponse;importjavax.servlet.http.HttpServletRequest;importorg.apache.shiro.web.filter.authc.FormAuthenticationFilter;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;public class SessionFilter extendsFormAuthenticationFilter {private Logger logger = LoggerFactory.getLogger(SessionFilter.class);private final static String X_REQUESTED_WITH_STRING = "X-Requested-With";private final static String XML_HTTP_REQUEST_STRING = "XMLHttpRequest";private final static String SESSION_OUT_STIRNG = "sessionOut";
@Overrideprotected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throwsException {if (this.isLoginRequest(servletRequest, servletResponse)) {if (this.isLoginSubmission(servletRequest, servletResponse)) {return this.executeLogin(servletRequest, servletResponse);
}else{return true;
}
}else{if(isAjax((HttpServletRequest) servletRequest)) {
servletResponse.getWriter().print(SESSION_OUT_STIRNG);
}else{this.saveRequestAndRedirectToLogin(servletRequest, servletResponse);
}return false;
}
}public booleanisAjax(HttpServletRequest httpServletRequest) {
String header=httpServletRequest.getHeader(X_REQUESTED_WITH_STRING);if(XML_HTTP_REQUEST_STRING.equalsIgnoreCase(header)) {
logger.debug("当前请求为Ajax请求:{}", httpServletRequest.getRequestURI());returnBoolean.TRUE;
}
logger.debug("当前请求非Ajax请求:{}", httpServletRequest.getRequestURI());returnBoolean.FALSE;
}
}
2.覆盖默认shiro拦截器
@BeanpublicShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean= newShiroFilterFactoryBean();//必须设置 SecurityManager
shiroFilterFactoryBean.setSecurityManager(securityManager);//如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
shiroFilterFactoryBean.setLoginUrl("/login");//登录成功后要跳转的链接
shiroFilterFactoryBean.setSuccessUrl("/index");//未授权界面;
shiroFilterFactoryBean.setUnauthorizedUrl("/403");//自定义拦截器
Map filtersMap = new LinkedHashMap();//限制同一帐号同时在线的个数。
filtersMap.put("kickout", filterKickoutSessionControl());
shiroFilterFactoryBean.setFilters(filtersMap);//权限控制map.
Map filterChainDefinitionMap = new LinkedHashMap();
filterChainDefinitionMap.put("/servlet/authimage", "anon");
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
Map filters=new LinkedHashMap<>();
filters.put("authc", newSessionFilter());
shiroFilterFactoryBean.setFilters(filters);returnshiroFilterFactoryBean;
}
这个是重点:
Map filters=new LinkedHashMap<>();
filters.put("authc", newSessionFilter());
shiroFilterFactoryBean.setFilters(filters);
3.改造前端
一开始采用了修改form提交的参数,把iframe=false就可以提交X-Requested-With,但是这样的异步请求实在太多,不仅仅在form提交,还有combo,tree等等。所以最后用了网上说的方法,改造$.ajax达到统一处理。
//首先备份下jquery的ajax方法
var _ajax =$.ajax;//重写jquery的ajax方法
$.ajax = function(opt) {//备份opt中error和success方法
var fn ={
error :function(XMLHttpRequest, textStatus, errorThrown) {
},
success :function(data, textStatus) {
}
}if(opt.error) {
fn.error=opt.error;
}if(opt.success) {
fn.success=opt.success;
}//扩展增强处理
var _opt =$.extend(opt, {
error :function(XMLHttpRequest, textStatus, errorThrown) {debugger;
erro= eval("(" + XMLHttpRequest.responseText + ")");//错误方法增强处理
fn.error(XMLHttpRequest, textStatus, errorThrown);
},
success :function(data, textStatus) {if (data != ‘sessionOut‘) {
fn.success(data, textStatus)return false;
}else{
top.location.href= appPath + "/";
}
}
});return_ajax(_opt);
};
这个地方要根据个人情况修改一下:
原文:http://www.cnblogs.com/huiy/p/7497954.html