在 ASP.NET 中重用会话 ID 的方式和原因

文章翻译 文章翻译
文章编号: 899918 - 查看本文应用于的产品
展开全部 | 关闭全部

简介

本文介绍使用 Microsoft ASP.NET 会话 ID 的方式和云因。

更多信息

ASP.NET 会话状态是一种允许您存储服务器端、特定于用户的数据的技术。Web 应用程序可以使用这些数据处理来自为其实例化会话状态的用户的请求。会话状态用户由会话 ID 标识。通过使用以下方法之一传送会话 ID:
  • 会话 ID 是发送到用户浏览器的 Cookie 的一部分。
  • 会话 ID 嵌入在 URL 中。此技术也称为“无 Cookie 会话”。
会话 ID 是一个由 20 个字符组成的字符串表示的 120 位随机数。字符串的格式设置为可以包含在 URL 中并且不必进行 URL 编码。例如,可以在无 Cookie 会话中使用字符串。传送会话 ID 的最常用方法是通过使用 Cookie 来存储会话 ID。

当用户第一次打开 Web 浏览器并转到某个实现 ASP.NET 会话状态的网站时,将向浏览器发送一个名为“ASP.NET_SessionId”并包含由 20 个字符组成的值的 Cookie。

当用户在相同的 DNS 域中浏览时,Web 浏览器将继续向作为源的域发送此 Cookie。

例如,app1.tailspintoys.com 和 app2.tailspintoys.com 都是 ASP.NET 应用程序。如果用户先后转到 app1.tailspintoys.com 和 app2.tailspintoys.com,则这两个应用程序将会使用相同的 Cookie 和相同的会话 ID,以跟踪用户在每个应用程序内的会话状态。应用程序之间不会共享相同的会话状态。应用程序之间只共享会话 ID。

因此,可以出于多种原因重用会话 ID。例如,如果重用会话 ID,则不必执行下面的操作:
  • 当向您提供有效的会话 ID 时,将创建一个新加密的唯一会话 ID。
  • 为单个域中的每个 ASP.NET 应用程序创建新的会话 ID。
当 Web 应用程序要求登录并提供注销页或选项时,建议您在用户注销网站后清除会话状态。若要清除会话状态,请调用“Session.Abandon”方法。使用“Session.Abandon”方法可以刷新会话状态,而无需等到会话状态超时。默认情况下,超时时间为 20 分钟的可调过期。每当用户向网站发出请求并提供会话 ID Cookie 时都会刷新此过期期限。“Abandon”方法在指示应放弃会话状态的会话状态对象中设置一个标志。在页面请求的末尾将检查该标志并进行处理。因此,在调用“Abandon”方法之后,用户可以在页面中使用会话对象。一旦完成页面处理,即会删除会话。

当使用进程内会话状态模式时,这些会话状态对象将存储在 HttpCache 中。当满足下面的条件时,HttpCache 支持回调方法:
  • 删除了缓存项。
  • 会话状态管理器注册了在删除缓存项时要调用的“Session_OnEnd”事件处理程序。
当会话状态管理器删除驻留在缓存中的会话状态对象时,HttpCache 管理器将调用所有已注册的回调。实际上,此行为将引发“Session_OnEnd”事件处理程序。

当您放弃会话时,将不会从用户的浏览器中删除会话 ID Cookie。因此,一旦放弃会话,对同一个应用程序的任何新请求都将使用相同的会话 ID,但具有新的会话状态实例。同时,如果用户在相同的 DNS 域内打开另一个应用程序,则在从一个应用程序调用“Abandon”方法后,用户将不会丢失其会话状态。

有时,您可能不希望重用会话 ID。如果是这样而且您了解不重用会话 ID 的后果,请使用下面的代码示例以放弃会话并清除会话 ID Cookie:
Session.Abandon();
Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));
此代码示例从服务器中清除会话状态,并将会话状态 Cookie 设置为空值。空值可以有效地从浏览器中清除 Cookie。

当用户没有从应用程序注销并且发生会话状态超时时,应用程序可能仍将使用同一个会话状态 Cookie(如果没有关闭浏览器)。 此行为将导致用户转到登录页,并且提供用户的会话状态 Cookie。 为了保证在打开登录页 (login.aspx) 时使用新的 ID,应将空 Cookie 发送回客户端。为此,将 Cookie 添加到响应集合中。然后,将响应集合发送回客户端。发送空 Cookie 的最简单方法是通过使用“Response.Redirect”方法。由于 Cookie 集合对于 ASP.NET_SessionId 始终具有一个值,因此您不能仅仅测试此 Cookie 是否存在,这样将会创建一个“Response.Redirect”循环。可以针对重定向到登录页设置查询字符串。

或者,可以使用不同的 Cookie 来通知您是否已经重定向到登录页,如下面的代码示例所示。为了帮助提高安全性,确保没有任何用户尝试通过使用 ASP.NET Cookie 和另一个 Cookie 来打开登录页,下面的代码示例使用“FormsAuthentication”类来对 Cookie 数据进行加密和解密。然后,代码示例设置 5 秒钟的超时时间。
private void Page_Load(object sender, System.EventArgs e)
{ 
if( !IsPostBack && 
( Request.Cookies["__LOGINCOOKIE__"] == null ||
Request.Cookies["__LOGINCOOKIE__"].Value == "" ) )
{
//At this point, we do not know if the session ID that we have is a new
//session ID or if the session ID was passed by the client. 
//Update the session ID.

Session.Abandon();
Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));

//To make sure that the client clears the session ID cookie, respond to the client to tell 
//it that we have responded. To do this, set another cookie.
AddRedirCookie();
Response.Redirect( Request.Path );
}

//Make sure that someone is not trying to spoof.
try
{
FormsAuthenticationTicket ticket =
FormsAuthentication.Decrypt( Request.Cookies["__LOGINCOOKIE__"].Value );

if( ticket == null || ticket.Expired == true ) 
throw new Exception();

RemoveRedirCookie();
}
catch
{
//If someone is trying to spoof, do it again.
AddRedirCookie();
Response.Redirect( Request.Path );
}


Response.Write("Session.SessionID="+Session.SessionID+"<br/>");
Response.Write("Cookie ASP.NET_SessionId="+Request.Cookies["ASP.NET_SessionId"].Value+"<br/>");
} 

private void RemoveRedirCookie() 
{ 
Response.Cookies.Add(new HttpCookie("__LOGINCOOKIE__", "")); 
} 

private void AddRedirCookie()
{

FormsAuthenticationTicket ticket = 
new FormsAuthenticationTicket(1,"Test",DateTime.Now,DateTime.Now.AddSeconds(5), false,""); 
string encryptedText = FormsAuthentication.Encrypt( ticket ); 
Response.Cookies.Add( new HttpCookie( "__LOGINCOOKIE__", encryptedText ) );
}

属性

文章编号: 899918 - 最后修改: 2007年11月30日 - 修订: 1.2
这篇文章中的信息适用于:
  • Microsoft .NET Framework 1.1
关键字:?
kbhowto kbinfo KB899918
Microsoft和/或其各供应商对于为任何目的而在本服务器上发布的文件及有关图形所含信息的适用性,不作任何声明。 所有该等文件及有关图形均"依样"提供,而不带任何性质的保证。Microsoft和/或其各供应商特此声明,对所有与该等信息有关的保证和条件不负任何责任,该等保证和条件包括关于适销性、符合特定用途、所有权和非侵权的所有默示保证和条件。在任何情况下,在由于使用或运行本服务器上的信息所引起的或与该等使用或运行有关的诉讼中,Microsoft和/或其各供应商就因丧失使用、数据或利润所导致的任何特别的、间接的、衍生性的损害或任何因使用而丧失所导致的之损害、数据或利润不负任何责任。

提供反馈

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com