2013-05-11 65 views
0

在我的ASP.Net MVC應用程序中,如果用戶在ajax調用期間註銷或Session超時,那麼登錄頁面將作爲html返回到調用javascript ajax調用。這會導致客戶端發生錯誤,因爲它無法解析html。表單身份驗證是否將未登錄頁面返回爲未經授權訪問的html?

我想覆蓋authorize屬性上的handleunauthorizedrequest,但即使重寫它,在調試時也不會受到影響,並且仍會返回登錄頁面。

我的目標是返回一個狀態碼,如果請求是ajax請求並且請求未經授權。

這個問題的解決方案是什麼,我還是不明白爲什麼handleunauthorizedrequest沒有被擊中,是不是被覆蓋?

+0

您應用了新創建的自定義授權的controlers /動作屬性? – shakib 2013-05-11 19:52:59

+1

是的,但它仍不會覆蓋基類。重寫的方法是無用的,這是因爲即時通訊使用表單身份驗證? – Xerxes 2013-05-11 19:55:12

+0

你能發表一些代碼嗎? – shakib 2013-05-11 19:56:18

回答

0

在jquery的AJAX的jqXhr對象具有狀態屬性,它是像這樣進行訪問:

jqXhr.state() 

如果狀態屬性的值是「拒絕」,則它意味着一個JSON結果沒有返回,您的電話被拒絕。

我使用此屬性的值來確定會話是否超時,並且我能夠正常重定向到登錄頁面。

0

以下應該工作。

public class CustomAuthorizeAttribute : AuthorizeAttribute 
{ 
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
     var request = filterContext.HttpContext.Request; 
     var response = filterContext.HttpContext.Response; 
     if (request.IsAjaxRequest()) 
     { 
      response.StatusCode = 401; 
      filterContext.Result = new EmptyResult(); 
     } 
     else 
     { 
      base.HandleUnauthorizedRequest(filterContext); 
     } 
    } 
} 

然後使用在控制器或採取行動的濾波器作爲

//instead of Authorize 
[CustomAuthorize] 
public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(); 
    } 
} 

並在客戶端側的鉤添加到ajaxError事件,並檢查其狀態碼401

$(function(){ 
    $(document).ajaxError(function (e, xhr, opts) { 
     if (401 == xhr.status) { 
      //do whatever you like 
      //return document.location = document.location; 
     } 
    }); 
}); 

希望這有助於。

+0

我的問題是,保護覆蓋無效HandleUnauthorizedRequest不會被覆蓋,也不會被擊中。 – Xerxes 2013-05-11 21:14:02

+0

Aside'from System.Web.Mvc'命名空間,'System.Web.Http'命名空間下還有另一個'AuthorizeAttribute'類。你在和哪一個合作? – shakib 2013-05-11 21:27:00

+0

System.Web.Mvc有什麼區別? – Xerxes 2013-05-11 21:32:15

0

Default AuthorizeAttribute不處理AjaxRequest。你需要編寫你自己的實現。我在下面給出了一個示例實現,您可以根據需要進行自定義。

我在homecontroller中添加了一個操作來返回一個JsonResult並應用默認的[Authorize]屬性。

[Authorize] 
    public ActionResult SayHello() 
    { 
     object result=new {status="200",res="Hello"}; 
     return Json(result, JsonRequestBehavior.AllowGet); 
    } 

在視圖中,我添加了一個簡單的ajax事件來調用操作並將res顯示爲alert。

<h3> 
    <a id="anchorSayHello">Say Hello</a> 
</h3> 
@section Scripts{ 
    <script> 
     $('#anchorSayHello').click(function() { 
      $.ajax('/Home/SayHello', { 
       success: function(data) { 
        var str = data.res; 
        alert(str); 
       } 
      }); 
      return false; 
     }); 
    </script> 

} 

因爲,你已經告訴它它將返回一個html響應作爲未授權。現在

enter image description here

,讓我們實現自定義授權attribtue並適用於該訴訟

public class TestAuthorize : AuthorizeAttribute 
{ 
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
     if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest()) 
     { 
      object res = new { status = "404", redirect = "/Account/Login" }; 
      filterContext.Result = new JsonResult() { Data = res, JsonRequestBehavior = JsonRequestBehavior.AllowGet }; 

      return; 
     } 
     base.HandleUnauthorizedRequest(filterContext); 
    } 
} 

現在,讓我們修改JavaScript作爲,

$('#anchorSayHello').click(function() { 
      $.ajax('/Home/SayHello', { 
       success: function (data) { 
        if (data.status === '200') { 
         var str = data.res; 
         alert(str); 
        } else { 
         window.location = data.redirect; 
        } 
       } 
      }); 
      return false; 
     }); 

現在,應該按預期工作,爲ajax請求也會重定向到登錄頁面。

enter image description here

+1

正如我在問題中所說的,問題是overriden方法HandleUnauthorizedRequest不會被打到,因爲它沒有被覆蓋。 – Xerxes 2013-05-11 21:19:35

0

由於.NET 4.5的正確答案是設置HttpResponse[Base].SuppressFormsAuthenticationRedirect爲true:

if (!httpContext.Request.IsAuthenticated) 
{ 
    if (httpContext.Request.IsAjaxRequest()) 
    { 
     httpContext.Response.SuppressFormsAuthenticationRedirect = true; 
    } 
    return new HttpUnauthorizedResult(); 
} 
相關問題