SSRS:為什麼在“HTTP 400 Bad Request - Request Too Long”出現之前,SKA-cookies 會一直累積?
我已將 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 時,它又開始工作了。
我現在的問題是我不知道是什麼導致了這個“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">
