我已将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时,它又开始工作了 .
我现在的问题是我不知道导致这种“cookie溢出”的原因 . 我也不知道,如果这是Chrome中的一个错误,一个vanilla 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 timeout更改为720分钟 .
<authentication mode="Forms">
<forms loginUrl="logon.aspx" name="sqlAuthCookie" timeout="720" path="/">
</forms>
</authentication>
有没有人知道我可以做些什么来防止被Session Keep-Alive cookie淹没(除了手动删除这些cookie)?
对我来说这本身没问题,除了它非常讨厌,但它会成为一个问题,因为用户可能不会非常理解......
3 回答
Issue listed as fixed 在SQL Server 2012 SP1 CU7. 中(请参阅Microsoft在connect issue中的评论)
但仍然出现在SQL-Server 2014中 .
如果无法安装SQL Server 2012 SP1 CU7,则应用后面的部分:
好的,我自己得到了答案 .
每次打开报告时都会发出保持活动的cookie .
现在,当一个人打开(或刷新或更改另一个页面),例如超过110-120个报告而不关闭浏览器时,这就成了一个问题 .
因此,我们通过删除多余的cookie来保护,并在appx设置安全边界 . 假定最多120个 Cookies 的1/2 .
Cookie是HttpOnly,当关闭浏览器时会过期(会话cookie) .
它们是非安全的HttpOnly cookie,这就是我尝试通过JavaScript删除它们失败的原因 .
因此有必要在服务器端删除它们 . 由于我们无法修改ReportServer,因此我们必须使用内联脚本 .
您可以在ReportViewer Control http://msdn.microsoft.com/en-us/library/microsoft.reporting.webforms.reportviewer.keepsessionalive(v=vs.100).aspx上将KeepSessionAlive设置为false
由于我们网站的体系结构,我在实现这个问题的不同解决方案时遇到了很多困难 - 无论出于何种原因,我的同事最初决定使用带有报告链接的iframe而不是ReportViewer控件,我不愿意尝试改变由于简单的cookie问题,在开发过程中这么晚 .
我试过的解决方案 did not 工作:
Implementing Stefan's code-behind fix - 我页面上的服务器代码无法访问嵌入式iframe文档中设置的cookie
Changing cookies from the parent document in javascript - 出于可以理解的安全原因,我无法从客户端代码访问iframe中的cookie
Tried passing parameters into the report URL to tell it not to keep the session alive - 尝试追加"&rs:KeepSessionAlive=False",这不会导致错误,但无法正常工作
Toyed with the idea of injecting javascript into the reports themselves - 考虑到这将涉及更改大约50多个报告并搞砸导出/保存的报告功能,这不是一个选项
最后,在浏览服务器之后,我意识到 Report Server "Pages" folder (C:\ Program Files \ Microsoft SQL Server \ MSRS11.SQLEXPRESS \ Reporting Services \ ReportServer \ Pages)包含 "ReportViewer.aspx" 文档 .
你知道什么? It's just a simple ASP.NET page with a header where you can add your own javascript!?
所以,这是 what DID work for me:
我刚刚添加了client-side cookie-setting code I had found elsewhere以删除ReportViewer页面上的所有cookie,一切都突然起作用了!一次只有一个保持活跃的cookie!
请注意,页面中有一些我没有替换的预先存在的代码 .
希望这对其他人有所帮助,因为我在这个问题上挣扎了一段时间!
NOTE: 请注意,在我的情况下,Session Keep Alive(SKA)cookie不仅仅是HTTP,所以我能够从客户端访问它们,尽管只是报告服务器本身的客户端 .