从.NET 3.0升级到3.5:在Web Garden中,设置为StateServer的站点将恢复为InProc

Nic*_*cki 5 .net asp.net session state state-server

场景:

使运行.NET 3.0的服务器和在启用了Web园的应用程序池中运行的ASP.NET Web站点(进程数:3).web.config配置如下:

    <sessionState
      cookieless="UseCookies"
      cookieName=".authz"
      mode="StateServer"
      regenerateExpiredSessionId="true"
      stateConnectionString="tcpip=127.0.0.1:42424"
      timeout="60"
      useHostingIdentity="true" />

现在将计算机升级到.NET 3.5 SP1.重新启动服务器.结果:不再在w3wp.exe的实例之间维护会话,就好像所有会话都还原为InProc一样.目前的解决方法是减少到1个工作进程.

奇怪的是:不同服务器上的相同代码没有遇到任何问题.我之前遇到过这个问题,但重启后神奇地消失了.我已经重新开始了一次,但到目前为止还没有快乐.

比较两台服务器的两台machine.configs和web.configs:相同.

其他人遇到过这个问题,但没有回答.

有任何想法吗?我真的很难过这个.

Nic*_*cki 11

所以,这个真是太神奇了.

满足以下所有条件时,似乎会出现此问题:

  • 您正在运行Windows Server 2003(IIS 6.0)和ASP.NET 2.0网站.
  • 该网站配置为使用Web Gardens,其中最大工作进程数大于1.因此,您已将应用程序配置为使用进程外会话存储; 在这种情况下,ASP.NET状态服务在本地计算机上运行.
  • 应用程序池标识不是设置为NETWORK SERVICE,而是设置为您根据部署最佳实践创建的自定义低权限用户帐户.
  • 您运行一个更新.NET框架的安装程序; 在我的例子中,这是从.NET 3.0到.NET 3.5 SP1的更新.

当升级完成并重新启动服务器时,您会发现刷新页面时会丢失会话变量,因为只有1/3的机会获得原始工作进程以满足原始请求.但这并不重要,因为您正在使用ASP.NET状态服务.什么破了?

使用ASP.NET状态服务时,ASP.NET使用一个名为machineKey加密和/或散列所有会话数据的值来存储(我不知道它是加密还是散列,或者两者兼而有之,但它不是一个重要的区别,这个讨论).这样,当任何工作进程使用会话标识符从服务请求数据时,可以确保数据在存储在外部数据源中时未被篡改.

如果您在Web场中,则可能machineKeyweb.config文件中定义了静态,并且不会发生此问题.但是对于单服务器Web园景,您可能依赖于默认machineKey设置,该设置设置AutoGenerate,IsolateApps为ASP.NET 2.0应用程序.这意味着ASP.NET会自动生成应用程序池独有的计算机密钥.它根据某种算法重新生成此密钥,但这对于此讨论并不重要.

生成的值通常存储在注册表中HKLM\SOFTWARE\Microsoft\ASP.NET\2.0.50727.0\AutoGenKeys\{SID of the Application Pool Identity}.但是.NET Framework安装程序错误(我确实认为这是一个错误)会破坏此注册表项,并且为了加重侮辱,会重置此密钥的权限,以便您的自定义应用程序池标识无法写入注册表项创建新的机器密钥.

结果是,在Web园中旋转的每个工作进程都使用它自己及时生成的机器密钥的内存副本,从而有效地创建了Web场景.例如,工作进程A旋转,看到没有AutoGenKey条目存在(实际上,它甚至无法读取它),生成自己的条目并开始使用它来散列发送到ASP.NET状态服务的数据.它尝试将此新计算机密钥保存到注册表项,但无提示失败.工作进程B旋转,看到没有AutoGenKey条目存在,生成自己的条目并开始使用来散列数据...你会看到它的去向.

结果是您现在使用三个不同的机器密钥散列会话数据.虽然会话标识符的数据存在,但三个工作进程中有两个会将其拒绝为无效/篡改,因为它使用自己的密钥.

您可以通过machineKeyweb.config文件中明确设置自定义来解决此问题.

或者,您可以aspnet_regiis.exe -ga MachineName\ApplicationPoolUserName在命令提示符下重新运行以修复损坏的权限.

你的问题解决了.该睡觉了.


更新6月30日:根据我在Microsoft Connect发布此问题的报告,Microsoft表示他们已修复安装程序,以便从升级到.NET 4开始不会发生此行为.未来所有3.0/3.5升级都可能发生这种情况所以我会留下这个问题/答案.