ASP.NET服务器如何知道会话终止的时间?

时间:2014-07-16 13:34:38

标签: asp.net session state-management

据我所知,Session对象用于存储每个会话的数据。我做了以下实验:

  1. 打开浏览器并访问aspx页面A,它将一些数据保存到Session对象。
  2. 保持浏览器打开并打开另一个选项卡以访问显示会话数据的aspx页面B.它就像我在步骤1中存储一样显示。
  3. 我关闭浏览器并重新访问页面B,存储的数据消失了。
  4. 从3开始,似乎服务器端以某种方式检测到我(客户端)已终止会话。但是当我与Fiddler核实时,当我在第3步关闭浏览器时,没有任何位发送到服务器。

    那么ASP.NET应用程序怎么可能知道我的第3步请求是针对新的会话?

    会话是如何定义的?不同的标签是否始终属于同一会话?

    ADD 1

    虽然会话数据可以显示在页面A和页面B中,但是它们中显示的会话ID是不同的。为什么呢?

    正确

    第A页和第B页的会话ID相同。我没有使用InPrivate浏览。

    ADD 2

    确实有会话ID的Cookie:

    ASP.NET_SessionId=lmswljirqdjxdfq3mvmbwroy; path=/; domain=localhost; HttpOnly
    

    在响应POST请求时设置。

    所以我做了另一个实验,关闭了浏览器(Fire Fox),正如预期的那样,Cookie不再存在。我手动创建cookie,希望“伪造的Cookie可以带回原来的会话。”但是Fiddler表示手动cookie根本没有发送。

    菲德勒说:

    This request did not send any cookie data.
    

    可以伪造一个cookie并恢复之前的会话吗?

    会话在服务器上存在多长时间?

2 个答案:

答案 0 :(得分:7)

当服务器启动新会话时,它会为会话生成新的标识符。会话数据存储在会话提供程序中的此标识符/密钥下(可以是内存中,SQL Server中或完全不同的内容,具体取决于您的配置 - 通常在web.config中配置)。

同时,服务器向您的浏览器发送cookie(至少在默认设置中)。此cookie包含会话的标识符。这就是服务器如何将您的请求与您的特定会话相关联:在每个请求中,您的浏览器都会发送会话cookie。服务器从cookie中检索标识符,并使用标识符查找会话数据。

会话cookie是非持久性的,这意味着在浏览器关闭时将删除cookie。这就是会话被删除looks like的原因:会话数据仍然存在于服务器上,但由于会话cookie已被删除,浏览器不会发送会话cookie,因此服务器会考虑这是新会话的开始,创建一个新的会话标识符等。因此,服务器并不真正知道会话何时结束,它只知道会话何时开始。这就是为什么在默认的SQL Server支持的设置中,预定作业将清除非活动会话 - 否则会话数据将永远停留在数据库中。

有关会话的更多信息,使用没有Cookie的会话,会话配置,提供商等,请参阅MSDN

关于是否在浏览器标签之间共享会话:这实际上取决于是否在标签之间共享Cookie。我认为cookie是在所有主流浏览器的标签之间共享的,我认为如果它们不是,它会相当混乱,但是没有什么能阻止某人创建一个不在标签之间共享cookie的浏览器。 / p>

编辑1

如果删除会话cookie,理论上可以通过重新创建cookie来重新创建会话。这本身不是安全问题,因为您正在重新创建您已有权访问的数据。但是,如果其他人要重新创建会话cookie,那将是一个安全问题。你可以google" ASP.NET会话劫持"如果你想看看这个。

编辑2

会话基本上存在于服务器上,直到某些东西被清除。因此,会话的生命周期取决于您存储它的位置。如果将其存储在内存中,则会在应用程序被回收时删除会话(可能是因为您在IIS中回收应用程序或因为服务器已重新启动)。如果您将它存储在SQL Server中,会话数据将一直存在,直到作业删除它,因为它已经被访问了一段时间(抱歉,我不记得详细信息,但您可以将它们谷歌) 。如果将会话数据存储在Azure表存储中,则可能永远不会清除它们。

注意

ASP.NET会话状态的两个重要细节经常被忽视:

  1. 当会话存储在进程外部时(例如,在SQL Server中),您要存储的数据必须是可序列化的。
  2. 为了在访问会话数据时防止竞争条件,访问会话的请求将被序列化,也就是说,它们并发执行。
  3. 可在the MSDN article "Underpinnings of the Session State Implementation in ASP.NET"

    中找到更多详细信息

答案 1 :(得分:1)

本文提供了有关ASP.NET Session(http://msdn.microsoft.com/en-us/library/vstudio/ms178581(v=vs.100).aspx

的更多详细信息

这个想法很简单。

  1. 当您访问页面时,会生成会话ID并将其设置为cookie。还为该会话ID启动了计时器。
  2. 当你不断回来时,计时器会重置。如果您在请求其他页面之前等待足够长的时间,计时器将过期,您的会话将无效。此时将生成一个新会话。
  3. 回答你的问题: 如果您打开多个标签,它们将“共享”会话。因为您的浏览器正在从所有这些选项卡发送会话cookie。 但是,如果您打开Firefox和Chrome。这两个浏览器不会共享会话。因为,他们不共享cookie。

    当您关闭浏览器时,您的会话仍然有效。如果您在会话到期之前访问该网站上的页面,您将无法获得新会话。这就是为什么,建议始终注销。通过这种方式,该网站知道您将离开,并将代表您销毁会话。

    问:虽然会话数据可以显示在页面A和页面B中,但它们中显示的会话ID是不同的。 A:你确定吗?所有页面的会话ID都应相同。如果您从一个浏览器访问页面A而从另一个浏览器访问页面B,则会有所不同。

    ADD2

    您的浏览器设置可能是在Windows关闭时销毁cookie。请仔细检查选项中是否设置为记住历史记录。

    Cookie可以伪造。如果攻击者可以获得会话ID,他们可以在他们的最后伪造一个cookie。我不确定Fiddler是否允许您手动创建cookie。您需要深入了解文档。或者也许这里的其他人可以回答这个问题。