Asp.net 形成身份验证 cookie 不遵守 IIS7 的超时

Posted

技术标签:

【中文标题】Asp.net 形成身份验证 cookie 不遵守 IIS7 的超时【英文标题】:Asp.net forms authentication cookie not honoring timeout with IIS7 【发布时间】:2010-12-18 03:32:52 【问题描述】:

身份验证 cookie 似乎在短时间内(一天左右)后超时。我正在使用表单身份验证,并且在 web.config 中设置了带有 slipExpiration="false" 的 timeout="10080"。使用该设置,cookie 应在用户成功通过身份验证后大约 7 天过期。

这与 IIS6 宣传的一样,但是当我将站点移至 IIS7 时,cookie 过期得更快。我已经在多台使用 IE 和 Firefox 的机器上确认了这种行为,这让我相信这是 IIS7 设置。

是否存在与身份验证相关的特定于 IIS7 的隐藏设置?除匿名用户跟踪外,网站的所有其他身份验证类型均已禁用。

【问题讨论】:

您是否使用过 FireFox 中的开发人员工具查看 cookie 数据,并查看到期日期? 是的,cookie 设置为在配置 web.config 时过期。但是,出于某种原因,cookie 提前到期,我需要重新登录。正如我所提到的,这发生在多台带有多个浏览器的计算机上。 可能 cookie 没有过期,但其他一些东西会杀死它 出于兴趣:你在使用会话状态吗?如果不是,如果你这样做(通过在会话开始时将某些东西、任何东西放入会话状态)会发生什么?该领域似乎存在一些有趣的错误,可以通过确保初始化会话状态来解决。 不,这仍然是个谜。到目前为止,我一无所有地失去了 300 个代表点...... 【参考方案1】:

身份验证 cookie 使用来自本地 web.config 或全局 machine.configmachineKey 值加密。如果没有明确设置这样的密钥,则会自动生成一个密钥,但它不会持久化到磁盘上——因此,每当应用程序重新启动或由于不活动而“回收”时,它都会改变,并且新键将在下一次点击时创建。

解决问题很简单,只需将<machineKey> 配置部分添加到web.config,或者可能(最好?)添加到服务器上的machine.config(未经测试):

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

Google generate random machinekey 可以为您生成此部分的网站。不过,如果您的应用程序处理机密信息,您可能希望自己创建密钥。

【讨论】:

到目前为止,这似乎已经解决了问题。我会给它几天时间,如果一切正常,我会将其标记为答案。 @Jørn 这行得通,但我似乎无法将其标记为已回答...也许是因为这是一个赏金问题? 我认为你对赏金的看法是对的 - 我有一个老悬赏问题的行为方式相同。 这可能是一个旧答案,但我花了大约 2 个小时试图弄清楚为什么我的会话 cookie 似乎随机丢失。这解决了它! 该链接不再有效,但可以通过谷歌搜索“生成随机机器密钥”以获取生成它们的网站。【参考方案2】:

我的理解是cookies是被消费方——浏览器过期的,也就是说IIS在这方面没有发言权

【讨论】:

我也是这么理解的。不过,我已经在多台计算机和操作系统上对此进行了测试和验证。 您是否尝试按照 Josh 的建议去做 - 您是否在浏览器中看到了 cookie 你能把cookie的文字贴出来吗? 名称 dmbstream 值 主机 dmbstream.com 路径/安全 无过期 Mon, 07 Dec 2009 15:33:12 GMT 您对这个 cookie 的到期时间有什么期望?是格林威治标准时间 2009 年 12 月 7 日星期一 15:33:12 吗?实际偏离了多少?如果是小时,则可能与时区有关【参考方案3】:

将 IIS 中配置的会话状态设置为 进行中 使用 Cookie 超时=您需要的时间 使用主机身份进行模拟

还将 EnableSessionState 设置为 true(这也是默认设置)

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

希望你的问题能解决。

【讨论】:

经典模式不是一个选项,也不应该要求它按预期工作。【参考方案4】:

首先我必须说这些“指南”是通用的,而不是 iis-7 独有的。 在&lt;system.web&gt;下的web.config中 您要么拥有&lt;sessionState mode="StateServer" stateConnectionString="tcpip=localhost:42424" timeout="130" cookieless="false"/&gt;(这需要在本地主机上运行 ASP.NET 会话状态服务器服务) 或&lt;sessionState mode="InProc" timeout="130" cookieless="false"/&gt;。 主要区别在于,在 InProc 中,会话状态数据放置在应用程序进程本身中。在另一种设置中,不同的服务正在执行存储,您的应用程序只需轮询它以获取所需的数据。 InProc 使用了这两种(以及 sql-server 会话状态模式)是最不可靠但最快的。 Sql-server 是最可靠和最慢的,StateServer 模式处于中间位置,仅在电源/系统故障的情况下不可靠。话虽如此,我必须说,对于请求计数较低的站点,性能损失可以忽略不计。

现在,我的经验表明,InProc 的稳定性非常难以预测;我曾经和你有同样的问题。我能够通过调整应用程序池的设置来扩展应用程序的稳定性,我通过切换到 SessionState 完全解决了这个问题(这也允许关闭应用程序并且不会丢失会话状态数据)。

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

    IIS 和应用程序池。网站的每个虚拟目录都分配给一个应用程序池(默认为“DefaultAppPool”),该应用程序池具有一系列设置,您可以在其中定义进程“回收”的间隔 - 并因此保留系统资源。如果您不更改设置,应用程序可能会触发进程回收器的条件之一,这意味着您的应用程序被破坏

    防病毒。 在 ASP.NET 应用程序中,如果 web.config(以及应用程序所依赖的任何子 .config 文件)文件被触及,应用程序将重新启动。现在有些情况下,防病毒程序可能会接触 web.config 文件(比如一天一次?),因此应用程序会重新启动,会话数据会丢失。

    配置错误 特别是对于表单身份验证,与时间相关的设置和行为总是依赖于网络会话,而身份验证会话位于网络会话之下。

我不知道表单身份验证模块是否仅依赖于会话域,或者它是否也将数据放置在应用程序域中。如果是第二种情况,那么您可能必须禁用应用程序池中的所有回收设置,并再次检查配置/防病毒以及谁存储会话数据。

【讨论】:

我认为表单身份验证根本不使用会话状态,因为它分配了自己的AuthCookie。不过,我可能错了。 可能是这样,但它们可以连接;如果第一个失败了,另一个则效仿。【参考方案5】:

我最近遇到了同样的问题,即我的网站每 20 分钟超时一次,即使我将会话超时设置为 2 小时。我发现这是因为 IIS 工作进程每 20 分钟超时一次:http://technet.microsoft.com/en-us/library/cc783089(WS.10).aspx

【讨论】:

以上是关于Asp.net 形成身份验证 cookie 不遵守 IIS7 的超时的主要内容,如果未能解决你的问题,请参考以下文章

从 ASP.NET Core 1.1 MVC 迁移到 2.0 后,自定义 cookie 身份验证不起作用

Cookie 身份验证 ASP.NET Core

asp.net cookie、身份验证和会话超时

ASP.NET Core 身份验证 cookie 只收到一次

ASP.Net Core Cookie 身份验证

根据 ASP.NET 中的角色设置身份验证 cookie 超时长度