为什么/何时会话写入容易受到线程终止的影响?

问题描述 投票:5回答:3

代码:

Session["foo"] = "bar";  
Response.Redirect("foo.aspx");

问题:

[当foo.aspx从会话中读取“ foo”时,它不存在。 会话在那里,但是“ foo”没有任何值。

我在我们的生产环境中间歇性地观察到了这一点。但是我并不是要问a question about Response.Redirect()

说明:

Bertrand Le Roy解释(粗体是我的::

现在,重定向的功能是发送一个客户端的特殊标头,以便它要求服务器提供其他信息页面比它正在等待的页面要多。发送此消息后,在服务器端标头,重定向结束响应。这是非常暴力的事情。Response.End实际上停止了无论页面在哪里执行使用ThreadAbortException。什么真的发生在这里是会话令牌丢失在战斗中。

我的收获是,Response.Redirect()可以使用结束线程来处理。如果这些会话写得太过用力,那可能会威胁到我的会话写。

问题:

ASP.NET会话管理如何使它容易受到此攻击?在会话写入行“结束”之前,Response.Redirect()代码行才开始执行-怎么会对我的会话写入构成威胁?

在下一行代码执行之前,会话写入不会“完成”吗?还有其他情况下会话写入类似(好像从未发生过)丢失的情况吗?

asp.net session volatile response.redirect risk-analysis
3个回答
2
投票

我对会话编写的内部知识还不熟悉,但是我认为它具有一些复杂性,因为它依赖于将浏览器会话cookie转换为服务器标识。另外,我不确定运行时中的ThreadAbortExceptions do have special considerations,它可能会在此处播放。

在任何情况下,Response.Redirect()都有一个布尔值重载,可让您指定是否要结束线程。

Response.Redirect(string url,  bool endResponse);

如果将endResponse设置为“ false”进行调用,它将正常完成,而不是在内部调用Thread.Abort()。但是,这意味着它还将在完成之前执行页面生命周期中剩余的所有代码。

一个很好的折衷方案是先呼叫Response.Redirect(url, false),然后呼叫Application.CompleteRequest()。这将允许您进行重定向,但也可以使用最少的附加生命周期处理来正常关闭当前执行上下文。


1
投票

在测试了几种替代方法(Response.Redirect(...,false),Server.Transfer()和其他我现在不记得的“解决方案”之后,我们仅找到了一个可靠的答案)。 >

将会话状态从InProc移到SqlServer可以有效地从我们的系统中消除此行为,从而使Response.Redirect(...)完全可靠。如果进一步的测试表明不是这样,我将在此处报告,但我要说一下,要在您的环境中停止此操作:将会话状态移至SqlServer(或者“超出InProc”的状态就足够好了吗?我不确定)。 >

应用程序池回收会导致您的会话消失。您可以将应用程序池配置为在固定时间(建议在晚上或使用率低的时段)进行回收,或者增加应用程序池回收的超时时间。


0
投票

应用程序池回收会导致您的会话消失。您可以将应用程序池配置为在固定时间(建议在晚上或使用率低的时段)进行回收,或者增加应用程序池回收的超时时间。

© www.soinside.com 2019 - 2024. All rights reserved.