2017-09-27 147 views
0

我在我的asp.net mvc應用程序中覆蓋了HandleUnauthorizedRequest方法,以確保它向未經授權的Ajax調用發送401響應,而不是重定向到登錄頁面。當我在本地運行它時,它的工作狀態非常好,但是我部署到IIS後,我的重寫方法不會被調用。調試點根本不打我的方法,並立即被重定向到登錄頁面。部署到IIS後,自定義授權屬性不起作用

這是我的代碼:

public class AjaxAuthorizeAttribute : AuthorizeAttribute 
    { 
     protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
     { 
      if (filterContext.HttpContext.Request.IsAjaxRequest()) 
      { 
       filterContext.HttpContext.Response.Clear(); 
       filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized; 

       filterContext.Result = new JsonResult 
       { 
        Data = new 
        { 
         success = false, 
         resultMessage = "Errors" 
        }, 
        JsonRequestBehavior = JsonRequestBehavior.AllowGet 
       }; 
       filterContext.HttpContext.Response.End(); 
       base.HandleUnauthorizedRequest(filterContext); 
      } 
      else 
      { 
       var url = HttpContext.Current.Request.Url.AbsoluteUri; 
       url = HttpUtility.UrlEncode(url); 
       filterContext.Result = new RedirectResult(ConfigurationManager.AppSettings["LoginUrl"] + "?ReturnUrl=" + url); 
      } 
     } 
    } 

,我有我的控制器的頂部聲明屬性[AjaxAuthorize]。一旦將它部署到IIS後有什麼不同?

更新: 下面是我的測試,這是非常簡單的,甚至不管它是一個Ajax請求或一個簡單的頁面刷新後登錄會話已過期 -

  1. 我部署將該網站放到我的本地IIS上
  2. 登錄網站,進入主頁 - 「/ Home」
  3. 右鍵單擊「註銷」鏈接,「在新選項卡中打開」 - 確保主頁仍在當前標籤上打開,而 會話被記錄ou噸。
  4. 刷新主頁。現在在這裏,調試點應該打開我覆蓋的HandleUnauthorizedRequest方法,並通過 if/else條件,然後將我重定向到登錄頁面。但它 不!它只是簡單地重定向到登錄頁面。我是 認爲它甚至沒有考慮我的自定義授權屬性。

但是,當我從Visual Studio運行該網站時,一切正常,控制進入我的覆蓋方法的調試點,並通過if/else條件。

+0

'一旦部署到IIS後會有什麼不同?'''ConfigurationManager.AppSettings [「LoginUrl」]' - 你檢查了你的配置文件嗎? – NightOwl888

+0

是的,我檢查,它指向「帳戶/登錄」。但問題是,在部署到IIS後,即使我完全刪除了「LoginUrl」的配置設置,它仍然會重定向到「帳戶/登錄」,該控件甚至不會輸入我的自定義屬性的'HandleUnauthorizedRequest'方法只有在我部署之後。我嘗試在調試和發佈配置中部署,但同樣的問題 –

回答

0

當您將您的網站部署到IIS時,默認情況下它將在IIS集成模式下運行。這通常是最好的選擇。但這也意味着HTTP請求/響應模型在授權檢查期間未完全初始化。我懷疑這導致IsAjaxRequest()在您的應用程序託管在IIS上時始終返回false

此外,default HandleUnauthorizedRequest implementation看起來是這樣的:

protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
     // Returns HTTP 401 - see comment in HttpUnauthorizedResult.cs. 
     filterContext.Result = new HttpUnauthorizedResult(); 
    } 

實際上,通過調用base.HandleUnauthorizedRequest(context)要覆蓋JsonResult實例,你是用默認HttpUnauthorizedResult實例設置。

有一個原因叫做過濾器。它們用於過濾進入邏輯塊的請求,而不是用於實際執行該邏輯塊。處理程序(ActionResult派生類)應該完成這項工作。

要完成此操作,您需要構建一個單獨的處理程序,以便過濾器執行的邏輯等待,直到HttpContext完全初始化。

public class AjaxAuthorizeAttribute : AuthorizeAttribute 
{ 
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
     filterContext.Result = new AjaxHandler(); 
    } 
} 

public class AjaxHandler : JsonResult 
{ 
    public override void ExecuteResult(ControllerContext context) 
    { 
     var httpContext = context.HttpContext; 
     var request = httpContext.Request; 
     var response = httpContext.Response; 
     if (request.IsAjaxRequest()) 
     { 
      response.StatusCode = (int)HttpStatusCode.Unauthorized; 

      this.Data = new 
      { 
       success = false, 
       resultMessage = "Errors" 
      }; 
      this.JsonRequestBehavior = JsonRequestBehavior.AllowGet; 
      base.ExecuteResult(context); 
     } 
     else 
     { 
      var url = request.Url.AbsoluteUri; 
      url = HttpUtility.UrlEncode(url); 
      url = ConfigurationManager.AppSettings["LoginUrl"] + "?ReturnUrl=" + url; 
      var redirectResult = new RedirectResult(url); 
      redirectResult.ExecuteResult(context); 
     } 
    } 
} 

注:上面的代碼是未經測試。但是這應該讓你朝着正確的方向前進。