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

标签 asp.net cookies reporting-services forms-authentication ssrs-2012

我已将 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 保持事件?)cookie 时,它​​又开始工作了。

SSRS Sucks

我现在的问题是我不知道是什么原因导致了这个“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,据我所知,与表单例份验证无关,而与 Vanilla SSRS 有关。

我认为造成这种情况的唯一原因是将 forms-authentication-cookie 超时更改为 720 分钟,我在 web.config 文件的 forms-authentication 部分中输入了该值。

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

有谁知道我可以采取什么措施来防止被 session 保持事件 cookie 淹没(手动删除这些 cookie 除外)?

这对我本身来说没有问题,除了非常烦人之外,但这将是一个问题,因为用户可能不太理解这一点......

最佳答案

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

<小时/>

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

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

每次打开报告时都会发出 keep-alive cookie。
现在,当用户在不关闭浏览器的情况下打开(或刷新或更改到另一页面)(例如超过 110 - 120 个报告)时,这就会成为问题。

因此,我们通过删除多余的 cookie 来进行保护,并在 appx 处设置安全边界。假设最多 120 个 cookie 的 1/2。

cookie 是 HttpOnly,当关闭浏览器时就会过期( session 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">

关于asp.net - SSRS : Why do SKA-cookies build up until "HTTP 400 Bad Request - Request Too Long" occurs?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18491223/

相关文章:

c# - 网站中实体模型的命名空间

asp.net - Dart可以使用WCF服务吗?

c# - Page_Init 方法异常中的 DotNetNuke 重定向

php - 子域的 Magento cookie 设置

node.js - Express.js session 未定义。雷迪斯

javascript - 在 ScriptManager.RegisterStartupScript 后面的代码中调用脚本后,jQuery document.ready 不会触发

javascript - Angular cookie 在不同的 url 不返回相同的值

reporting-services - SSRS中Tablix列的动态宽度调整

sql-server - RDLC 报告 - 使用子报告作为报告标题

ssrs-2008 - 电子邮件订阅的 SSRS 动态文件名