【MS的一道面试题】Session问题
前天一个朋友去面试MS,被问到一个问题,请大家帮忙看看:
访问ASP/ASP.NET站点时,当一个客户端请求的Session被另一个客户端看到了,可能是什么原因造成的?
问题点数:20、回复次数:30Top
1 楼hc8513589()回复于 2006-04-24 11:05:38 得分 0
数据串联Top
2 楼cxyppppp()回复于 2006-04-24 11:07:59 得分 0
请详细解释一下原因,并且这种情况发生的概率为千分之一Top
3 楼LoveCherry(论成败,人生豪迈;大不了,重头再来!^_^)回复于 2006-04-24 11:20:59 得分 0
面试技术支持?Top
4 楼firstsee(华仔)回复于 2006-04-24 11:24:37 得分 0
我也遇到这种问题,请那位大虾给解释一下Top
5 楼beiouwolf(beiouwolf)回复于 2006-04-24 12:19:06 得分 0
应该是恰巧生成了两个同样的SESSIONID
由于SESSIONID存放于COOKIE,以区别不同的客户端
所以会两个客户端访问到一个SESSION
Top
6 楼hchxxzx(NET?摸到一点门槛)回复于 2006-04-24 12:55:05 得分 0
可能原因是两个人使用同一台机器,前者没有注销用户,后者继续使用相同网站.Top
7 楼cxyppppp()回复于 2006-04-24 14:26:56 得分 0
题目已经说明是不同的客户端了,呵呵Top
8 楼hdt(倦怠)回复于 2006-04-24 14:42:05 得分 0
web.config 中
sessionstate = Inproc ?
Top
9 楼ghchen()回复于 2006-04-24 14:42:27 得分 0
beiouwolf(beiouwolf)应该是正确的Top
10 楼rainy816(笨笨猪)回复于 2006-04-24 14:43:23 得分 0
使用SESSION是很容易就被别人看到或者篡改的。毕竟客户端输入的数据是不稳定不可估计的。 一般最好不要用SESSION。
SESSION为全局的,每实例化一次就会分配一个SESSION资源。不管是同一台或者是不同的都容易出问题。除非你的SESSION是不变的。Top
11 楼tanzhilong(cheney)回复于 2006-04-24 14:43:50 得分 0
应该没错啊Top
12 楼cen123(C#.NET)回复于 2006-04-24 15:06:57 得分 0
同意hdt(倦怠) 看法,有可能把环境变量保存到数据库中,以导致两个客户端读取了同一个SESSION。Top
13 楼artoksxb(进取人生)回复于 2006-04-24 15:39:27 得分 0
用代理,有没有可能Top
14 楼star0796(star0796)回复于 2006-04-24 15:44:00 得分 0
beiouwolf(beiouwolf)的是正确答案!!Top
15 楼ericfine(埃里克)回复于 2006-04-24 16:30:42 得分 0
提到了ASP,所以SESSION应该是INPROC的,而且COOKIELESS=FALSE
SESSIONID相同的机率极低
最大的可能性是另一个用户知道了前者的SESSIONID, 并修改了自己浏览器进程里的SESSIONID
题中说的“客户端”,是指PC机还是浏览器?Top
16 楼scow(怡红快绿之小橙子|和谐权是第4代人权)回复于 2006-07-31 17:45:44 得分 0
输出缓存造成的,要禁用内核缓存模式Top
17 楼kevin_gao(困了!累了!睡觉了!)回复于 2006-07-31 17:57:27 得分 0
是不是啊,我以为不大可能哈,学习。Top
18 楼blackhero(黑侠客)回复于 2006-07-31 18:02:00 得分 0
Session是Server端对象,另一客户端如何看见Top
19 楼zhaochunyu0104(春雨)回复于 2006-08-22 22:51:06 得分 0
学习Top
20 楼yiruoyun(肄若芸)回复于 2006-08-22 23:00:57 得分 0
因为MS很垃圾啊:)Top
21 楼amandag(高歌)回复于 2006-08-23 00:11:50 得分 0
会话和输出缓存
谈到输出缓存,ASP.NET 1.1 和 ASP.NET 2.0 都存在一个潜在的问题,该问题会影响在 Windows Server™ 2003 和 IIS 6.0 上运行的服务器中的输出缓存页。我曾经亲眼看到该问题在 ASP.NET 生产服务器中出现过两次,这两次都是通过关闭输出缓冲来解决的。后来我了解到有一个比禁用输出缓存更好的解决方案。以下是我第一次遇到该问题时的情况。
当时的情况是这样的,某个网站(我们在此称为 Contoso.com,它在小型 ASP.NET Web 领域中运行公共电子商务应用程序)与我的团队联系,抱怨他们遇到了“跨线程”错误。使用 Contoso.com 网站的客户常常突然丢失已经输入的数据,但却看到另一用户的相关数据。稍做分析即发现,跨线程这个描述并不准确;“跨会话”错误更为贴切。看起来 Contoso.com 是在会话状态中存储数据的,由于某些原因,用户会偶尔随机地连接到其他用户的会话。
我的一个团队成员编写了一个诊断工具,用来将每个 HTTP 请求和响应的关键要素(包括 Cookie 标头)记录到日志中。然后,他将该工具安装在 Contoso.com 的 Web 服务器上,并让其运行了几天。结果非常明显。大概每 100000 个请求中会发生一次这样的情况:ASP.NET 正确地为全新会话分配一个会话 ID 并返回 Set-Cookie 标头中的会话 ID。然后,它会在下一个紧相邻的请求中返回相同的会话 ID(即,相同的 Set-Cookie 标头),即使该请求已经与一个有效的会话相关联并且正确提交了 Cookie 中的会话 ID。实际上,ASP.NET 是随机将用户从他们自己的会话中切换出去并将他们连接到其他会话。
我们很惊讶,于是开始寻找原因。我们首先检查了 Contoso.com 的源代码,让我们感到欣慰的是,问题不在那。接着,为了确保问题与应用程序宿主在 Web 领域无关,我们只保留一个服务器在运行,而关闭了所有其他服务器。问题仍然存在,这并不意外,因为我们的日志显示匹配的 Set-Cookie 标头绝不会来自两个不同的服务器。ASP.NET 意外地生成了重复的会话 ID,这令人难以置信,因为它使用 .NET Framework RNGCryptoServiceProvider 类生成这些 ID,并且会话 ID 的长度足以确保相同的 ID 决不会生成两次(至少在下一个万亿年内不会生成两次)。除此之外,即使 RNGCryptoServiceProvider 错误地生成了重复的随机数字,也无法解释 ASP.NET 为何不可思议地将有效的会话 ID 替换为新的 ID(不唯一)。
凭直觉,我们决定看一下输出缓存。当 OutputCacheModule 缓存 HTTP 响应时,它必须小心不要缓存了 Set-Cookie 标头;否则,包含新会话 ID 的缓存响应会将缓存响应的所有接收者(以及其请求生成了缓存响应的用户)连接到同一会话。我们检查了源代码;Contoso.com 在两个页面中启用了输出缓存。我们关闭了输出缓存。结果,应用程序运行数天而没有发生一个跨会话问题。此后,它运行了两年多都没有发生任何错误。在具有不同应用程序和一组不同 Web 服务器的另一家公司中,我们看到完全相同的问题也消失了。就像在 Contoso.com 一样,消除输出缓存就能解决问题。
Microsoft 后来确认此行为源于 OutputCacheModule 中的问题。(当您阅读本文时,可能已经发布了更新。)当 ASP.NET 与 IIS 6.0 一起使用并且启用内核模式缓存时,OutputCacheModule 有时无法从它传递给 Http.sys 的缓存响应中删除 Set-Cookie 标头。下面是导致出现错误的特定事件顺序:
• 最近没有访问网站(因此也没有对应的会话)的用户请求一个启用了输出缓存的页面,但是其输出当前在缓存中不可用。
• 该请求执行用于访问用户最新创建的会话的代码,从而导致会话 ID Cookie 在响应的 Set-Cookie 标头中返回。
• OutputCacheModule 向 Http.sys 提供输出,但是无法从响应中删除 Set-Cookie 标头。
• Http.sys 在后续的请求中返回缓存响应,误将其他用户连接到会话。
故事的寓意又是什么呢?会话状态和内核模式输出缓存不能混合使用。如果您在启用输出缓存的页中使用会话状态,并且应用程序在 IIS 6.0 上运行,则您需要关闭内核模式输出缓存。您仍将受益于输出缓存,但是因为内核模式输出缓存比普通输出缓存快得多,所以缓存不会同样有效。有关此问题的详细信息,请参见 support.microsoft.com/kb/917072。
您可以通过在页面的 OutputCache 指令中包含 VaryByParam="*" 属性来关闭单个页面的内核模式输出缓存,虽然这样做可能导致内存需求骤增。另一种更安全的方法是通过在 web.config 中包含下列元素来关闭整个应用程序的内核模式缓存:
<httpRuntime enableKernelOutputCache="false" />
您还可以使用注册表设置来全局性地禁用内核模式输出缓存,即禁用全部服务器的内核模式输出缓存。有关详细信息,请参见 support.microsoft.com/kb/820129。
每次我听到客户报告会话发生了费解的问题,我都会询问他们是否在任何页面中使用了输出缓存。如果确实使用了输出缓存,并且宿主操作系统是 Windows Server 2003,我会建议他们禁用内核模式输出缓存。问题通常就会迎刃而解。如果问题没有解决,则错误存在于代码中。警惕!
Top
22 楼amandag(高歌)回复于 2006-08-23 00:12:36 得分 0
请参看
http://www.microsoft.com/china/msdn/library/webservices/asp.net/WebAppFollies.mspx?mfr=trueTop
23 楼jianyi0115(随意)回复于 2006-08-23 00:21:41 得分 0
看到了???
无cookie Session?
还是盗窃了Cookie?Top
24 楼wisdomone()回复于 2006-09-07 13:50:17 得分 0
upTop
25 楼eyis(光芒上线)回复于 2006-09-07 15:35:06 得分 0
他在忽悠我 不可能看的见 除非两个人同时用一台机器Top
26 楼terry_12(大撒发射点)回复于 2006-09-07 15:45:49 得分 0
每次浏览器请求的时候,浏览器会发送SessionID到服务端,如果更改SessionID就有可能访问到其他用户的Session.因为SESSIONID是服务器控制的,出现的几率很小Top
27 楼terry_12(大撒发射点)回复于 2006-09-07 15:52:30 得分 0
应该是恰巧生成了两个同样的SESSIONID
由于SESSIONID存放于COOKIE,以区别不同的客户端
所以会两个客户端访问到一个SESSION
---------------------------------------------
我觉得不是服务器的问题.
如果是的话,肯定是MS的bug,既然MS知道,肯定要修正.Top
28 楼lshvs2008()回复于 2006-09-07 15:53:55 得分 0
有可能是一个用户登陆, 没有注销(清空Session),
另一个用户有 同时登陆,
这种情况是发生在: 一个(IE客户端)用户同时注册了多个用户 ,
而服务器 保存会话 却是用的 Session,
以后不要用这个, 可能用GUID + 传递字符串方式,
安全又不出错,
小弟正在做一个人才网, 就出现了这样的问题,
一个人想注册多个用户, 还想 订阅多个职位, 不发生 错误是不可能的。
Top
29 楼Eri(NULL)回复于 2007-03-12 21:45:38 得分 0
terry_12(大撒发射点) ( ) 信誉:100 Blog 2006-9-7 15:52:31 得分: 0
应该是恰巧生成了两个同样的SESSIONID
由于SESSIONID存放于COOKIE,以区别不同的客户端
所以会两个客户端访问到一个SESSION
---------------------------------------------
我觉得不是服务器的问题.
如果是的话,肯定是MS的bug,既然MS知道,肯定要修正.
这个确实是Bug啊,有个kb专门讲这个的,就是生成了一样的SessionID
而且还是在很极端的情况下发生的,我找找看,我看过这篇文章。
因此有这个现象:
cxyppppp() ( ) 信誉:96 Blog 2006-4-24 11:08:00 得分: 0
请详细解释一下原因,并且这种情况发生的概率为千分之一
Top
30 楼Eri(NULL)回复于 2007-03-12 21:58:03 得分 0
郁闷,没注意看,上面有人贴出来了,晕Top




