1. 程式人生 > >Shiro攔截器,在登入時判斷是ajax請求返回json,普通請求跳轉頁面

Shiro攔截器,在登入時判斷是ajax請求返回json,普通請求跳轉頁面

在使用shiro時,會遇到普通的頁面請求以及api介面呼叫的請求,因此需要區別對待來判斷是跳轉登入頁面還是返回json的資料:

1.建立攔截器

package org.zyyd.base.filter;

import com.alibaba.fastjson.JSONObject;

import org.apache.shiro.web.filter.authc.UserFilter;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.PrintWriter;

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

@Component("ApiCustomUser")
public class ApiCustomUserFilter extends UserFilter {

    /**
     * 攔截時返回  JSON,而不是跳轉到一個loginUrl
     */
    @Override
    protected boolean onAccessDenied(ServletRequest request,
                                     ServletResponse response) throws Exception {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;

        if(isAjaxRequest(req)){
            JSONObject json = new JSONObject();
            json.put("code", "-999");
            json.put("message", "尚未登入!");

            writeJson(json,res);
        }else{
            redirectToLogin(request, response);
        }

        return false;
    }


    /**
     *   是否是Ajax請求
     * @Description:
     * @param
     * @return
     * @throws
     * @author pengbin <pengbin>
     * 2018/11/26 10:58
     */
    public static boolean isAjaxRequest(HttpServletRequest request) {
        String requestedWith = request.getHeader("x-requested-with");
        if (requestedWith != null && requestedWith.equalsIgnoreCase("XMLHttpRequest")) {
            return true;
        } else {
            return false;
        }
    }


    /**
     *   輸出JSON
     * @Description:
     * @param
     * @return
     * @throws
     * @author pengbin <pengbin>
     * 2018/11/26 10:59
     */
    private void writeJson(JSONObject json, HttpServletResponse response) {
        PrintWriter out = null;
        try {
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            out = response.getWriter();
            out.write(json.toJSONString());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }
}

繼承shiro的UserFilter並且重寫onAccessDenied

2.修改配置:

<!-- 對應於web.xml中配置的那個shiroFilter -->
	<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<!-- Shiro的核心安全介面,這個屬性是必須的 -->
		<property name="securityManager" ref="securityManager"/>
		<!-- 要求登入時的連結(登入頁面地址),非必須的屬性,預設會自動尋找Web工程根目錄下的"/login.jsp"頁面 -->
		<property name="loginUrl" value="/login.html"/>
		<!-- 登入成功後要跳轉的連線(本例中此屬性用不到,因為登入成功後的處理邏輯在LoginController裡硬編碼) -->
		<!-- <property name="successUrl" value="/" ></property> -->
		<!-- 使用者訪問未對其授權的資源時,所顯示的連線 -->
		<!--<property name="unauthorizedUrl" value="/error/unauthorized"/>-->

        <!-- Shiro連線約束配置,即過濾鏈的定義 -->
        <!-- 此處可配合這篇文章來理解各個過濾連的作用http://blog.csdn.net/jadyer/article/details/12172839 -->
        <!-- 下面value值的第一個'/'代表的路徑是相對於HttpServletRequest.getContextPath()的值來的 -->
        <!-- anon:它對應的過濾器裡面是空的,什麼都沒做,這裡.do和.jsp後面的*表示引數,比方說login.jsp?main這種 -->
        <!-- authc:該過濾器下的頁面必須驗證後才能訪問,它是Shiro內建的一個攔截器org.apache.shiro.web.filter.authc.FormAuthenticationFilter -->
        <property name="filterChainDefinitions">
            <value>


                <!--/** =authc-->
				/** = ApiCustomUser

            </value>
        </property>

 

 

 

 

參考資料:https://blog.csdn.net/qq737050283/article/details/60876473