关于shiro中 ajax请求登录失效的处理

来源:互联网 发布:程序员赚钱吗 编辑:程序博客网 时间:2024/06/06 03:17

在公司项目中,与后台数据交互都是采用ajax请求进行数据交互。遇到当服务端会话失效后,页面无法跳转到登录页面。参考网上帮助处理如下。


1.自定义拦截器

public class UserFormAuthenticationFilter extends FormAuthenticationFilter {private static final Logger log = LoggerFactory.getLogger(UserFormAuthenticationFilter.class);@Overrideprotected 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, textStatus, errorThrown){                //错误方法增强处理                fn.error(XMLHttpRequest, textStatus, errorThrown);            },            success:function(data, textStatus,xhr){                //成功回调方法增强处理            if(data.code =='OSS.001'){             parent.location.href =contextPath+'/sys/manager/index';             return;};                fn.success(data, textStatus);            }        });        _ajax(_opt);    };})(jQuery);