SSRS:为什么SKA-cookies会在"HTTP 400 Bad Request - Request Too Long"发生之前建立起来?

Ste*_*ger 11 asp.net cookies forms-authentication reporting-services ssrs-2012

我已将SQL-Server Reporting Services 2012(SSRS 2012)切换为表单身份验证,以便我们可以通过Internet使用它.

我无法在任何地方找到SSRS 2012的表单身份验证示例,因此我必须使用SSRS 2008R2,并将其调整为2012年的单点登录(SSO).

在那一刻,一切似乎按预期工作; 我甚至设法让SSO跨域工作.

但现在我有一个问题:

我正在使用谷歌浏览器测试所有报告(超过200个),因为我必须插入一个改变td border-size的JavaScript,因为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;
        }


    }


}
Run Code Online (Sandbox Code Playgroud)

因为这段代码创建了一个人们在底部看到的"sqlAuthCookie".只有一个"sqlAuthCookie"所以我认为这可能不是一个表单身份验证错误.

问题似乎是SKA cookie,AFAIK与表单身份验证无关,与Vanilla SSRS有关.

我可以看到唯一的另一个原因是我在form.config文件的forms-authentication部分输入的forms-authentication-cookie timeout更改为720分钟.

  <authentication mode="Forms">
    <forms loginUrl="logon.aspx" name="sqlAuthCookie" timeout="720" path="/">
    </forms>
  </authentication>
Run Code Online (Sandbox Code Playgroud)

有没有人知道我可以做些什么来防止被Session Keep-Alive cookie淹没(除了手动删除这些cookie)?

对我来说这本身没问题,除了它非常讨厌,但它会成为一个问题,因为用户可能不会非常理解......

Ste*_*ger 8

在SQL Server 2012 SP1 CU7中列为已修复的问题.(请参阅Microsoft在连接问题中的评论)
但仍然存在于SQL-Server 2014中.


如果无法安装SQL Server 2012 SP1 CU7,则应用后面的部分:

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

每次打开报告时都会发出保持活动的cookie.
现在,当一个人打开(或刷新或更改另一个页面)时,例如超过110-120个报告,而不关闭浏览器,这就成了一个问题.

因此,我们通过删除多余的cookie来保护,并在appx设置安全边界.假定最多120个饼干的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">
Run Code Online (Sandbox Code Playgroud)