在公司项目中,与后台数据交互都是采用ajax请求进行数据交互。遇到当服务端会话失效后,页面无法跳转到登录页面。参考网上帮助处理如下。
public class UserFormAuthenticationFilter extends FormAuthenticationFilter { private static final Logger log = LoggerFactory.getLogger(UserFormAuthenticationFilter.class); @Override protected boolean onAccessDenied(ServletRequest request,ServletResponse response) throws Exception { 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() + "]"); } if(isAjax(request)){ response.getWriter().write(JSON.toJSONString(ResultBuilder.genExpResult(new AppBizException(AppExcCodesEnum.SESSION_TIMEOUT)))); }else{ this.saveRequestAndRedirectToLogin(request,response); } return false; } } private static boolean isAjax(ServletRequest request){ String header = ((HttpServletRequest) request).getHeader("X-Requested-With"); if("XMLHttpRequest".equalsIgnoreCase(header)){ return Boolean.TRUE; } return Boolean.FALSE; } }
2.注入filter
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterfactorybean"> <!-- Shiro的核心安全接口,这个属性是必须的 --> <property name="securityManager" ref="securityManager"/> <!-- 要求登录时的链接(可根据项目的URL进行替换),非必须的属性,默认会自动寻找Web工程根目录apos.htmlhtml"页面 --> <property name="loginUrl" value="/sys/manager/login"/> <!-- 登录成功后要跳转的连接 --> <property name="successUrl" value="/sys/manager/index"/> <!-- 用户访问未对其授权的资源时,所显示的连接 --> <!-- 若想更明显的测试此属性可以修改它的值,如unauthor.jsp--> <property name="unauthorizedUrl" value="/sys/manager/login"/> <property name="filters"> <map> <entry key="authc"> <bean class="com.xx.web.shiro.UserFormAuthenticationFilter" /> </entry> </map> </property> <!-- Shiro连接约束配置,即过滤链的定义 --> <!-- 下面value值的第一个'/'代表的路径是相对于HttpServletRequest.getcontextpath()的值来的 --> <!-- anon:它对应的过滤器里面是空的,什么都没做,这里.do和.jsp后面的*表示参数,比方说login.jsp?main这种 --> <!-- authc:该过滤器下的页面必须验证后才能访问,它是Shiro内置的一个拦截器org.apache.shiro.web.filter.authc.FormAuthenticationFilter --> <property name="filterChainDeFinitions"> <value> /statics/**=anon /js/**=anon /page/**=anon /sys/manager/login=anon /favicon.ico=anon /**=authc </value> </property> </bean>
3.ajax 请求不想改动以前代码,在jajax加个代理
(function($){ //备份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,errorThrown){ //错误方法增强处理 fn.error(XMLHttpRequest,errorThrown); },xhr){ //成功回调方法增强处理 if(data.code =='OSS.001'){ parent.location.href =contextpath+'/sys/manager/index'; return; }; fn.success(data,textStatus); } }); _ajax(_opt); }; })(jQuery);