Asp.net

SSRS:為什麼在“HTTP 400 Bad Request - Request Too Long”出現之前,SKA-cookies 會一直累積?

  • May 31, 2017

我已將 SQL-Server Reporting Services 2012 (SSRS 2012) 切換到表單身份驗證,以便我們可以通過 Internet 使用它。

我在任何地方都找不到 SSRS 2012 的表單身份驗證範例,因此我不得不採用 SSRS 2008R2 一個,並將其調整為 2012 年的單點登錄 (SSO)。

那時一切似乎都按預期進行。我什至設法讓 SSO 跨域工作。

但是現在我有一個問題:

我正在使用 Google Chrome 測試所有報告(超過 200 個),因為我必須插入一些 JavaScript 來改變 td 邊框大小,以便 HTML 在非 IE5-QuirksMode 下正確顯示。大約在第 50 次報告之後,我突然得到:

“HTTP 400 錯誤請求 - 請求太長”

在那之後,我無法查看任何其他報告,即使是之前確實有效的報告。

問題似乎是由太多 cookie 引起的,事實上,當我刪除一些“*_SKA”(Session Keep Alive?)cookie 時,它又開始工作了。

SSRS 很爛

我現在的問題是我不知道是什麼導致了這個“cookie 溢出”。我也不知道這是 Chrome 中的錯誤,香草 SSRS 中的錯誤還是新表單身份驗證引起的錯誤。

我在與 cookie 有關的新表單身份驗證中所做的一切是:

using System;
using System.Collections.Generic;
using System.Text;


namespace FormsAuthentication_RS2012
{


   internal class FormsAuthenticationWorkaround
   {

       public static void RedirectFromLoginPage(string strUser, bool createPersistentCookie)
       {
           //string url = System.Web.Security.FormsAuthentication.GetRedirectUrl(strUser, true);
           string url = GetRedirectUrlWithoutFailingOnColon(strUser, createPersistentCookie);
           SQL.Log("User: '" + strUser + "' ReturnUrl", url);

           if (System.Web.HttpContext.Current != null && System.Web.HttpContext.Current.Response != null)
               System.Web.HttpContext.Current.Response.Redirect(url);
       }


       // https://github.com/mono/mono/blob/master/mcs/class/System.Web/System.Web.Security/FormsAuthentication.cs
       // @MSFT: WTF are u guys smoking ?
       public static string GetRedirectUrlWithoutFailingOnColon(string userName, bool createPersistentCookie)
       {
           if (userName == null)
               return null;

           System.Web.Security.FormsAuthentication.SetAuthCookie(userName, true, "/");

           string returnUrl = null;

           if (System.Web.HttpContext.Current != null && System.Web.HttpContext.Current.Request != null)
               returnUrl = System.Web.HttpContext.Current.Request.QueryString["ReturnUrl"];

           if (returnUrl != null)
               return returnUrl;

           returnUrl = System.Web.Security.FormsAuthentication.DefaultUrl;
           return returnUrl;
       }


   }


}

由於這段程式碼創建了人們在底部看到的“sqlAuthCookie”。只有一個“sqlAuthCookie”,所以我認為這不可能是表單身份驗證錯誤。

問題似乎是 SKA cookie,AFAIK 與表單身份驗證無關,而與 Vanilla SSRS 無關。

我能看到的唯一其他原因是我在 web.config 文件的 forms-authentication 部分中輸入的 forms-authentication-cookie 超時更改為 720 分鐘。

 <authentication mode="Forms">
   <forms loginUrl="logon.aspx" name="sqlAuthCookie" timeout="720" path="/">
   </forms>
 </authentication>

有誰知道我可以做些什麼來防止被會話保持活動 cookie 淹沒(除了手動刪除這些 cookie)?

這對我本身來說沒有問題,除了它非常煩人之外,但這將是一個問題,因為使用者可能不會很理解這一點……

在 SQL Server 2012 SP1 CU7中****列為已修復的問題。(請參閱 Microsoft 在連接問題中的評論)

但仍然存在於 SQL-Server 2014 中。


如果您無法安裝 SQL Server 2012 SP1 CU7,則後面的部分適用:

好的,我自己得到了答案。

每次打開報告時都會發出保持活動 cookie。

現在,當一個人打開(或刷新或更改到另一個頁面)(例如,超過 110 - 120 個報告)而不關閉瀏覽器時,這就會成為一個問題。

所以我們通過刪除多餘的cookie來保護,並在appx設置一個安全邊界。假設最多 120 個 cookie 的 1/2。

cookie 是 HttpOnly,並在關閉瀏覽器時過期(會話 cookie)。

它們是不安全的 HttpOnly cookie,這就是我嘗試通過 JavaScript 刪除它們失敗的原因。

因此有必要在伺服器端刪除它們。由於我們不能修改 ReportServer,我們必須使用內聯腳本。

<body style="margin: 0px; overflow: auto">


<script type="text/C#" runat="server">
protected string ClearSessionKeepAliveCookiesToPreventHttp400HeaderTooLong()
{
   if(Request == null || Request.Cookies == null)
       return "";

   if(Request.Cookies.Count < 60)
       return "";

   // System.Web.HttpContext.Current.Response.Write("<h1>"+Request.Cookies.Count.ToString()+"</h1>");
   for(int i = 0; i < Request.Cookies.Count; ++i)
   {
       if(StringComparer.OrdinalIgnoreCase.Equals(Request.Cookies[i].Name, System.Web.Security.FormsAuthentication.FormsCookieName))
           continue;

       if(!Request.Cookies[i].Name.EndsWith("_SKA", System.StringComparison.OrdinalIgnoreCase))
           continue;

       if(i > 60)
           break;

       //System.Web.HttpContext.Current.Response.Write("<h1>"+Request.Cookies[i].Name+"</h1>");

       System.Web.HttpCookie c = new System.Web.HttpCookie( Request.Cookies[i].Name );
       //c.Expires = System.DateTime.Now.AddDays( -1 );
       c.Expires = new System.DateTime(1970, 1 ,1);
       c.Path = Request.ApplicationPath + "/Pages";
       c.Secure = false;
       c.HttpOnly = true;

       // http://stackoverflow.com/questions/5517273/httpcookiecollection-add-vs-httpcookiecollection-set-does-the-request-cookies
       //Response.Cookies[Request.Cookies[i].Name] = c;
       //Response.Cookies.Add(c);
       Response.Cookies.Set(c);
   }

   return "";
}


</script>

<%=ClearSessionKeepAliveCookiesToPreventHttp400HeaderTooLong()%>

   <form style="width:100%;height:100%" runat="server" ID="ReportViewerForm">

引用自:https://stackoverflow.com/questions/18491223