基於Spring Security的AJAX請求需要登錄的解決方案


當我們采用SpringSecurity進行安全控制時,除了正常的基於瀏覽器地址欄的請求URL安全攔截之外,還會經常遇到AJAX調用受權限攔 截的請求時返回值不能處理的情況,按照默認的配置,如果AJAX請求的url需要用戶登錄而用戶未登錄或者會話已過期了,這時會被自動攔截並轉到登錄界面 進行登錄,這時,ajax請求實際上是返回了登錄頁面的html代碼,這個代碼是不能進行json處理的。經過實驗,可以有兩個思路:

1、登錄頁面設置為某個 .do頁面,在這個頁面中做檢驗:

boolean isAjax = "XMLHttpRequest".equals(request.getHeader("X-Requested-With")); 
        //如果是ajax請求  
        if (isAjax) {         
            String jsonObject = "{\"success\":false,\"isLoginRequired\":true}";  
            String contentType = "application/json";  
            response.setContentType(contentType);  
            response.setCharacterEncoding("UTF-8");
            PrintWriter out = response.getWriter();  
            out.print(jsonObject);  
            out.flush();  
            out.close();  
            return;  
        }

判斷如果是ajax過來的請求,則返回一個json格式的字符串,用於前台處理。  前台如果是采用了jquery,可以擴展ajax請求,攔截所有的ajax請求的返回結果,進行全局處理:

(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) {
                // 成功回調方法增強處理
                if(data){
                    if (!data.success && data.isLoginRequired) {
                        showLoginWindow();
                    } else {
                        fn.success(data, textStatus);
                    }
                }


            }
        });
        _ajax(_opt);
    };
})(jQuery);

function showLoginWindow() {
    alert("請登錄");  //可根據需要定制
}

這種方式有一個不太好的地方:ajax全局攔截之后,提示登錄,然后就不會向下走了,這時如果彈出用戶登錄框進行登錄,則用戶登錄成功之后,以前的操作不會繼續執行了,用戶需要重新再去操作一下。

2、 還有一種方案,原理類似: 在安全中配置一個<access-denied-handler ref="accessDeniedHandler"/>, 但這個是存取拒絕的攔截處理,如果用戶還未登錄,是不會被攔截的,可以考慮在用戶匿名訪問時,默認創建一個特殊的用戶對象,這個用戶權限是很低的,沒有普 通用戶的權限,比如ROLE_USER,而我們一般會配置有權限的資源要求最低是有ROLE_USER角色也就是普通用戶身份,這樣,當用戶請求這個資源 時,會被安全拒絕,通常默認是轉到403錯誤頁面,如果配置了access-denied-handler,那么也可以轉到這個handler配置的一 個.do上去,再在這個do中按照上面的方法進行判斷處理。

這個方案不好的地方在於,不存在匿名用戶的說法了,因為通過用戶上下文來獲取當前用戶時,肯定會得到一個User對象。在這個handler中,需要處理用戶是否登錄的情況,如果未登錄,則轉到登錄頁面進行登錄,如果已登錄,則轉到真正的403頁面,或者json串。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM