Asp.net表单身份验证cookie在IIS7下不遵守超时时间

26

认证 cookie 似乎在短时间内就会超时(大约一天左右)。我正在使用 Forms 认证,web.config 中的 timeout =“10080”,slidingExpiration =“false”。设置后,cookie 应该在用户成功验证后大约过期7天。

在 IIS6 上,这个设置按照广告宣传的正常工作,但是当我将网站移动到 IIS7 时,cookie 的过期时间要快得多。我已经在多台计算机上用 IE 和 Firefox 确认了这种行为,这让我相信这是一个 IIS7 的设置问题。

是否存在一个与 IIS7 相关的隐藏设置,涉及认证方面?除了匿名用户跟踪之外,所有其他认证类型都已禁用。


你有使用过FireFox中的开发者工具来查看cookie数据并查看到期日期吗? - Josh Pearce
1
是的,而且cookie的过期时间被设置为web.config文件中配置的时间。但出于某种原因,cookie提前过期了,我需要重新登录。正如我所提到的,这在多台电脑上使用多个浏览器时都会发生。 - Jim Geurts
可能是Cookie没有过期,而是其他某个东西使其失效了。 - Omu
你是否使用了会话状态?如果没有,那么如果在会话开始时将任何内容放入会话状态中会发生什么?在这个领域似乎存在一些有趣的错误,通过确保初始化会话状态可以解决这些问题。 - Jeremy McGee
不,这仍然是个谜。到目前为止,我白白失去了300个声望点数... - Jim Geurts
5个回答

43

认证Cookie使用本地web.config或全局machine.config中的machineKey值进行加密。如果没有显式设置这样的键,则会自动生成一个键,但它不会持久保存到磁盘 - 因此,每当应用程序由于不活动而重新启动或“回收”时,它将更改,并且下一次命中将创建一个新的键。

解决这个问题就像在web.config中添加<machineKey>配置部分一样简单,或者可能(最好?)在服务器的machine.config中添加(未经测试):

<system.web>
  ...
  <machineKey 
    validationKey="..."
    decryptionKey="..."
    validation="SHA1"
    decryption="AES"/>
  ...
</system.web>

使用Google搜索“生成随机机器密钥”的网站,可以为您生成此部分。但如果您的应用程序涉及机密信息,则可能希望自己创建密钥。


到目前为止,这似乎已经解决了问题。我会再观察几天,如果一切正常,我会将其标记为答案。 - Jim Geurts
@Jørn 这个方法是有效的,但似乎我无法将其标记为已解决...也许是因为这是一个悬赏问题? - Jim Geurts
我觉得你关于赏金的看法是正确的 - 我有一个旧的赏金问题也出现了同样的情况。 - Jørn Schou-Rode
1
这可能是一个旧的答案,但我花了大约2个小时来尝试弄清楚为什么我的会话cookie似乎随机丢失。这修复了它! - MikeCov
该链接已失效,但可以通过谷歌搜索“生成随机机器密钥”来找到生成它们的网站。 - Stephen Oberauer

0

我的理解是,cookie的过期由消费方——浏览器决定,这意味着IIS对此没有发言权。


这也是我的理解。虽然我已经在多台计算机和操作系统上进行了测试和验证。 - Jim Geurts
你试过Josh建议的做法了吗?你在浏览器中看到cookie了吗? - mfeingold
你能发布一下cookie的文本吗? - mfeingold
名称 dmbstream 值 <已省略> 主机 dmbstream.com 路径 / 安全 否 过期时间 Mon, 07 Dec 2009 15:33:12 GMT - Jim Geurts
你对这个cookie何时过期有什么期望?是在Mon, 07 Dec 2009 15:33:12 GMT吗?实际时间偏差多少?如果是小时,可能与时区有关。 - mfeingold
那个特定的 cookie 刚刚过期了... 对我来说,这不是预期的行为。 - Jim Geurts

0

设置在IIS中配置的会话状态为 进程内 使用Cookies 超时时间=您所需的时间 使用托管标识进行模拟

同时将EnableSessionState设置为true(这也是默认值)

最重要的是以经典模式运行应用程序池。

希望您的问题能够解决。


2
经典模式不是一个选项,也不应该需要它来使得预期工作正常。 - Jim Geurts

0
首先,我必须说这些“指南”是通用的,而不是仅适用于IIS-7。 在web.config文件中的下, 你可以使用(需要在本地运行ASP.NET Session State Server服务) 或者。 主要区别在于,在InProc模式下,会将会话状态数据放置在应用程序进程本身中。在另一种设置中,不同的服务正在进行存储,并且您的应用程序只需轮询它以获取所需的数据。 经过使用两种模式(以及sql-server会话状态模式),InProc是最不可靠但最快的。Sql-server是最可靠但最慢的,而StateServer模式则介于两者之间,仅在发生电源/系统故障的情况下才不可靠。话虽如此,我必须说,对于请求计数较低的站点,性能损失是可以忽略不计的。

我的经验表明,InProc在稳定性方面相当不可靠;我曾经和你一样遇到了同样的问题。通过调整应用程序池的设置,我能够提高应用程序的稳定性,通过切换到SessionState(也允许关闭应用程序而不丢失会话状态数据)来彻底解决问题。

您可能遇到应用程序/会话稳定性的原因:

  1. IIS和应用程序池。每个网站的虚拟目录都分配给一个应用程序池(默认为“DefaultAppPool”),该池具有一系列设置,其中包括定义进程“循环使用”的时间间隔,从而保留系统资源。如果您不更改设置,则应用程序可能触发进程回收器的某个标准,这意味着您的应用程序出现故障了。

  2. 杀毒软件。 在ASP.NET应用程序中,如果触及web.config(以及应用程序所依赖的任何子.config文件)文件,应用程序将重新启动。现在有些情况下,杀毒软件可能会触及web.config文件(例如每天一次?),从而导致应用程序重新启动并且会话数据丢失。

  3. 错误的配置 特别是对于Forms身份验证,与身份验证会话相关的时间设置和行为总是依赖于Web会话。

我不知道的是Forms Authentication模块是否仅依赖于会话域,还是也将数据放置在应用程序域中。如果是后者的情况,那么您可能需要禁用应用程序池中的所有循环设置,并重新检查配置/防病毒软件以及储存会话数据的位置。

1
我认为表单身份验证根本不使用会话状态,因为它分配了自己的“AuthCookie”。虽然我可能是错的。 - Jørn Schou-Rode
可能是这种情况,它们可能会连接在一起;如果第一个失败了,另一个也会跟着失败。 - Jaguar

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接