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

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


1.自定义拦截器

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, 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);



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值