SSRS: Why do SKA-cookies build up until "HTTP 400 Bad Request - Request Too Long" occurs?

asp.net, cookies, forms-authentication, reporting-services, ssrs-2012

Solution

Issue listed as fixed in SQL Server 2012 SP1 CU7. (see comments from Microsoft in the connect issue) But still present in SQL-Server 2014.

The later section applies, if you can't install SQL Server 2012 SP1 CU7:

OK, got the answer myself.

The keep-alive cookie is issued every time one opens a report. Now, that becomes a problem when one opens (or refreshs, or changes to another page), say, more than 110 - 120 reports, without closing the browser.

So we safeguard by deleting the excess cookies, and set a safe boundary at appx. 1/2 of the assumed maximum of 120 cookies.

The cookies are HttpOnly, and expire when one closes the browser (session cookies). They are non-secure HttpOnly cookies, which is why I failed in my attempt to delete them via JavaScript. So it becomes necessary to delete them on the server side. Since we can't modify ReportServer, we have to use inline-scripting.

<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">

Problem

I have switched SQL-Server Reporting Services 2012 (SSRS 2012) to forms authentication so we can use it over internet. I could not find a forms-authentication sample for SSRS 2012 anywhere, so I had to take the SSRS 2008R2 one, and adapt it for 2012, for Single-Sign-On (SSO). At that point everything seemed to be working as expected; I even managed to get SSO working across domains. But now I have a problem: I was testing all reports (more than 200) with Google Chrome, because I had to insert a little JavaScript that alters td border-size for that the HTML displays right in non-IE5-QuirksMode. After about the 50th report, I suddenly got: "HTTP 400 Bad Request - Request Too Long" After that, I could not view any other report, not even those that did work previously. The problem seems to be caused by too many cookies, and indeed, when I deleted a few "*_SKA" (Session Keep Alive?) cookies, it began working again. My problem now is that I don't know what causes this "cookie overflow". I also don't know, if this a bug in Chrome, a bug in vanilla SSRS or a bug caused by the new forms authentication. All I do in the new forms-authentication that has something to do with cookies is this: ``` 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; } } } ``` And as this code creates the "sqlAuthCookie" that one sees at the bottom. There is only one "sqlAuthCookie" so I don't think this can possibly be a forms-authentication bug. The problem seem to be the SKA cookies, that AFAIK have nothing to do with forms-authentication and everything to do with Vanilla SSRS. The only other thing that I could see as a reason for this is the change in forms-authentication-cookie timeout to 720 minutes that I entered in the forms-authentication section in the web.config file. ``` <authentication mode="Forms"> <forms loginUrl="logon.aspx" name="sqlAuthCookie" timeout="720" path="/"> </forms> </authentication> ``` Does anybody know what I can do to prevent getting flooded by Session Keep-Alive cookies (except for deleting those cookies manually)? It's no problem for me per se, apart from it being highly annoying, but it's going to be a problem because the users probably won't be very understanding of that...

Original source

Related problems