Shiro拦截Ajax请求,认证失败重定向 dao到登录页面 (亲测有效)

由于 shiro  能 自动判断登录并返回登录登录页面,自动跳转到登录页面,返回login 页面 ,但是遇到ajax请求的 方法, 程序不会自动跳转到登录页面,所以需要 添加重定向方法  自动跳转到重定向 登录页面

1.自定义拦截器LoginFormFilter拦截器,继承FormAuthenticationFilter类,在需要登录而未登录的请求都会执行onAccessDenied请求。

import java.io.IOException;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;

import cn.net.polyinfo.utils.R;
 //添加注释,该注释很重要,需要 覆盖掉authc 方法的过滤器 
@Component("LoginFormFilter")
public class LoginFormFilter extends FormAuthenticationFilter {
 
    /**
     * 在访问controller前判断是否登录,返回json,不进行重定向。
     * @param request
     * @param response
     * @return true-继续往下执行,false-该filter过滤器已经处理,不继续执行其他过滤器
     * @throws Exception
     */
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        HttpServletRequest req = (HttpServletRequest)request;  

        //判断是否为ajax请求,默认不是  ,判断ajax 的方法有很多,需要根据项目的具体情况来判断,我的判断方法如下
        boolean isAjaxRequest = false;  
        if(!StringUtils.isBlank(req.getHeader("Accept" ))&& req.getHeader("Accept").equals("application/json, text/javascript, */*; q=0.01")){  
            isAjaxRequest = true;  
        }  
        String port = "",contextPath="";
        if(request.getServerPort()!=80){
            port = ":" + request.getServerPort();

        StringBuilder sb = new StringBuilder();
        sb.append(request.getScheme()).append("://").append(request.getServerName()).append(port).append(contextPath).append("/login");
        String loginPath =  sb.toString();   

        if (isAjaxRequest) {
            System.out.println("isAjax  请求");
            httpServletResponse.setCharacterEncoding("UTF-8");
            httpServletResponse.setContentType("application/json");
            httpServletResponse.getWriter().write(JSONObject.toJSON( R.error(HttpServletResponse.SC_FORBIDDEN, "登录认证失效,请重新登录!")).toString());
            httpServletResponse.setStatus(403);
            httpServletResponse.setHeader("REDIRECT", "REDIRECT");//告诉ajax这是重定向  
            httpServletResponse.setHeader("CONTEXTPATH", loginPath);//重定向地址  
            httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
    
            } else {
                saveRequestAndRedirectToLogin(request, response);
               
            }
        }
        return false;
    }
     
}

 

 

 

2、 修改shiro 过滤器的方法改为=自定义的过滤器 


	
	
	  
	      
	      
	      
	      
	      
	    
	      
	      
	      
	      
	      
	      
	      
	      
	      
	        
	        	/services/**=anon
	            /images/**=anon
	        	/statics/**=anon
				/api/**=anon
	        	/login.html=anon
	        	/recommend.html=anon
	         	/apages/**=anon
	        	/kindeditor/**=anon
	        	/error.html=anon
	        	/sys/login=anon
	        	/captcha.jpg=anon
	        	/**=LoginFormFilter
	        
	    
	
	

 

 

3、 js 修改 ,通过XMLHttpRequest取得响应头,REDIRECT     , 若HEADER中含有REDIRECT说明后端想重定向  

将该js放到 公用js中


/**
 * ajax默认设置
 * 包括默认提交方式为POST,
 * 判断后台是否是重定向
 */
$.ajaxSetup( {    
	
    //设置ajax请求结束后的执行动作    
    complete : function(XMLHttpRequest, textStatus) {  
    	
        // 通过XMLHttpRequest取得响应头,REDIRECT    
        var redirect = XMLHttpRequest.getResponseHeader("REDIRECT");//若HEADER中含有REDIRECT说明后端想重定向  
        if (redirect == "REDIRECT") {
            var win = window;    
            while (win != win.top){  
                win = win.top;  
            }
            //将后端重定向的地址取出来,使用win.location.href去实现重定向的要求  
            alert("您的登录信息已超时,请重新登录");
		 win.location.href= XMLHttpRequest.getResponseHeader("CONTEXTPATH");
        }
    },
    type:'POST'
});

测试成功

你可能感兴趣的:(Shiro拦截Ajax请求,认证失败重定向 dao到登录页面 (亲测有效))