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

來源:互聯網
上載者:User

當我們採用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串。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.