1

所以我发生了一些奇怪的事情,我无法确定是什么原因造成的。我的 asp.net 项目在使用以下命令同步的两台生产服务器上具有会话状态:

msdeploy -verb:sync -source:webserver,computername=%MACHINE%,username=Administrator,password=%PASSWORD% -dest:webserver 2<&1 

该应用程序是一个 asp.net 4.0 网站,在负载平衡配置后面的两台 Server 2008 R2 Web 服务器上运行,其中用户在连接后被设置为坚持使用一台服务器。我们<MachineKey>在应用程序的根站点中设置了带有验证和解密密钥的硬编码,并且在两个服务器之间是相同的。我的应用程序设置为将异常事件转发到我们的电子邮件系统。

发生的事情是我从服务器收到可怕的“视图状态 MAC 验证失败”,但即使服务器负载是 50/50 拆分,错误也会以 99/1 拆分出现。因此,一台 Web 服务器比另一台更频繁地生成这些错误。考虑到服务器已同步并且所有配置都相同,这很奇怪。

我已经对这个问题进行了广泛的搜索,似乎很难找到任何没有提及或执行以下操作的解决方案。

  • <MachineKey>服务器之间不完全相同。(我知道事实上这不是我的问题)
  • 设置enableViewStateMac=false或其他危害站点安全的设置。
  • 确保表单输入上的所有操作标记都引用它们所在的同一页面
  • 确保服务器的实例 ID 相同(它们是)
  • 如果用户在整个页面(视图状态)下载之前点击页面(我的视图状态设置为在页面顶部呈现)。
  • response.redirect 和 server.transfer 的问题

现在我已经消除了除了最后两个可能的原因之外的所有内容。我的应用程序已经运行了一年多,没有任何问题,就在这些错误出现之前,我启用了 SQL 会话状态,将项目从 .NET 3.5 迁移到 .NET 4.0,并将服务器模式部署模式设置为零售。我曾尝试回收应用程序池并执行“iis 重置”但无济于事。

还有其他人对我可以看什么有任何建议吗?底线我不想通过在我的网站上打开安全漏洞来解决这个问题。

用户第一次尝试登录时使用表单身份验证进行身份验证后似乎正在发生这种情况,但我无法确认这一点。我也有一个理论,这可能与缓存有关,但我也不能确定这一点。

这是我的 web.config 中的精彩部分(我删除了一些敏感信息)

    <system.web>
    <httpRuntime requestValidationMode="2.0"/>
    <globalization culture="en-US" uiCulture="en-US" resourceProviderFactoryType="WebResourceFactory"/>
    <compilation debug="true" defaultLanguage="c#" explicit="true" strict="true" targetFramework="4.0">
      <assemblies>
      </assemblies>
    </compilation>
    <authentication mode="Forms">
      <forms name=".ASPXAUTH" loginUrl="Login.aspx" protection="All" slidingExpiration="true"/>
    </authentication>
    <authorization>
      <deny users="?"/>
    </authorization>
    <sessionState mode="SQLServer" sqlConnectionString="connection" compressionEnabled="true" />
    <pages theme="Blue" controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID">
<machineKey validationKey="key" decryptionKey="key" decryption="3DES" validation="SHA1" />
    </system.web>

编辑:强调我正在使用带有负载平衡器的 SQL 会话状态,以更喜欢将用户路由到他们启动的服务器。

4

2 回答 2

0

好的,我似乎已经修复了它,虽然我无法辨别究竟是什么导致了它,所以我将列出我执行的所有步骤,以防其他人稍后遇到这个问题。

1:安装了这些 Windows 更新: 在此处输入图像描述

在此处输入图像描述

2:我的表单身份验证 cookie 设置为持久,但我的会话 cookie 设置为浏览器会话。我将表单身份验证 cookie 设置为基于浏览器会话。

3:我将我的站点配置复制到 IIS 的根目录。从所有文档中我发现我没有必要这样做,因为 IIS 应该支持不同站点/应用程序的多个机器密钥。

4:重启服务器。

而已!从那以后我没有收到错误。

于 2013-08-22T14:37:13.113 回答
0

还有一种可能是您没有添加到您的列表中 - ViewStateUserKey

我已经看到应用程序的问题,其中 ViewStateUserKey 在登录时设置为会话 ID,并且(至关重要)在任何数据保存到会话之前。由于 ASP.NET 在将一个或多个对象保存到会话之前不会保留会话 ID,这意味着 ID 不断变化,并且 Viewstate 验证失败。即使您已将某些内容保存到 Session ,如果您使用默认的进程内模型而不是状态服务器或 SQL 会话存储(正如您所做的那样),那么每个服务器上的 Session 也会有所不同。任何服务器特定的值或在与 ViewStateUserKey 一起使用的服务器之间不易预测的值当然也会导致此问题。

否则,我见过的这个问题的最常见原因是在表单上设置的“操作”属性与表单不是同一页面的 URL(这会发现使用 PHP 的开发人员或不尝试使用的平台)从 HTTP 抽象出来),或者在多服务器环境(您似乎已经涵盖)中的 Web.config 中缺少机器密钥属性。

于 2013-07-14T05:20:03.373 回答