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

smw*_*dia 2 asp.net session state-management

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

  1. 打开浏览器并访问aspx页面A,它将一些数据保存到Session对象.
  2. 保持浏览器打开并打开另一个选项卡以访问显示会话数据的aspx页面B. 它就像我在步骤1中存储一样显示.
  3. 我关闭浏览器并重新访问页面B,存储的数据消失了.

从3开始,似乎服务器端以某种方式检测到我(客户端)已终止会话.但是当我与Fiddler核实时,当我在步骤3中关闭浏览器时,没有任何位发送到服务器.

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

会话是如何定义的?不同的标签总是属于同一个会话吗?

添加1

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

正确

页面A和页面B中的会话ID相同.我没有使用InPrivate浏览.

添加2

会话ID确实有一个Cookie:

ASP.NET_SessionId=lmswljirqdjxdfq3mvmbwroy; path=/; domain=localhost; HttpOnly
Run Code Online (Sandbox Code Playgroud)

它是在响应POST请求时设置的.

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

提琴手说:

This request did not send any cookie data.
Run Code Online (Sandbox Code Playgroud)

那么伪造一个cookie并恢复以前的会话是可能的吗?

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

Run*_*une 7

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

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

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

有关会话的更多信息,使用没有cookie的会话,会话配置,提供程序等,请参阅MSDN.

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

编辑1

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

编辑2

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

注意

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

  1. 当会话存储在进程外部(例如,在SQL Server中)时,要存储的数据必须是可序列化的.
  2. 为了在访问会话数据时防止竞争条件,访问会话的请求将被序列化,也就是说,它们不会同时执行.

有关详细信息,请参阅MSDN文章"ASP.NET中会话状态实现的基础"