首次提交新会话的视图状态验证失败

问题描述

我们有一个在ASP.NET 4.5.2上运行的网站,该网站在新会话的第一个表单提交上(尤其是仅当该表单提交是该站点上的第一个回发时)引发以下viewstate错误。除非关闭浏览器并开始新的会话,否则随后提交的任何表单似乎都不错。如果先导航到站点的其他地方,然后转到表单,也不会发生这种情况。仅当您从头开始直接进入表单(即直接导航至登录页面)时。

Event code: 4009 
Event message: Viewstate verification failed. Reason: The viewstate supplied failed integrity check. 
Is authenticated: False 
Authentication Type: Forms 
Thread account name: IIS APPPOOL\.NET v4.5 
Exception message: Invalid viewstate.

已在Edge和Chrome中进行了报告/演示,但在Firefox或Internet Explorer中未进行报告/演示。

编辑:事实证明,在网站的初始浏览中,我们能够确定Edge和Chrome没有ASP.NET_SessionID会话cookie。回发后,会话ID将显示在cookie中,并且表单可以再次使用。在Firefox中不会发生这种情况,Firefox具有从第一页加载开始的.NET会话ID。该会话ID被用作ViewStateUserKey,这可能解释了错误的发生方式,但没有解释原因。为什么Chrome在回发之后才具有会话ID?

我已经在互联网上阅读了所有可以找到的有关此错误的内容,因此,基于我看到的其他建议,请允许我注意几件事:

  • 向网络配置文件添加机器密钥无济于事。我们已经尝试过了。另外,此站点不在服务器场上,而是在单个Web服务器上运行。
  • 我已经看到一些建议,可能涉及服务器上的应用程序池回收或内存限制,但是所讨论的服务器无法在其资源限制附近运行,并且该错误可以被一致地复制;如果与应用程序池事件或内存问题有关,我希望它会更加零星。

其他相关信息:

  • 服务器在Windows Server 2012 R2上运行IIS 8
  • Web配置中的
  • 身份验证设置为<authentication mode="Forms"><forms name="XXXXXXXXXX" loginUrl="SignIn.aspx" timeout="525600" /></authentication>
  • Web配置中的
  • 会话状态为<sessionState mode="InProc" cookieless="false" timeout="20" />

任何想法将不胜感激!

编辑:有人问如何提交表格。这是一个表单页面中的表单代码示例,我可以在该页面上重现错误,giftcard.aspx。

<form name="aspnetForm" method="post" action="./giftcard.aspx" onsubmit="javascript:return WebForm_OnSubmit();" id="aspnetForm">
<div>
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/[gibberish]" />
</div>
<script type="text/javascript">
//<![CDATA[
var theForm = document.forms['aspnetForm'];
if (!theForm) {
    theForm = document.aspnetForm;
}
function __doPostBack(eventTarget,eventArgument) {
    if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
        theForm.__EVENTTARGET.value = eventTarget;
        theForm.__EVENTARGUMENT.value = eventArgument;
        theForm.submit();
    }
}
//]]>
</script>
<script src="/WebResource.axd?[gibberish]" type="text/javascript"></script>
<script src="jscripts/formvalidate.js" type="text/javascript"></script>
<script src="jscripts/core.js" type="text/javascript"></script>
<script src="/ScriptResource.axd?[gibberish]" type="text/javascript"></script>
<script src="/ScriptResource.axd?[gibberish]" type="text/javascript"></script>
<script src="/ScriptResource.axd?[gibberish]" type="text/javascript"></script>
<script src="/WebResource.axd?[gibberish]" type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
function WebForm_OnSubmit() {
if (typeof(ValidatorOnSubmit) == "function" && ValidatorOnSubmit() == false) return false;
return true;
}
//]]>
</script>

我们正在使用asp:Button控件进行提交,如下所示:

<asp:Button ID="btnContinue" CssClass="btn-primary btn-GCcontinue" runat="server" Text="Continue" OnClick="btnContinue_Click" />

该示例将是网站上典型的表单。

解决方法

事实证明,答案与Samesite cookie有关。我们最近将会话ID Cookie更新为使用samesite = none,以解决我们怀疑与Chrome的相同网站更改有关的付款处理问题。当我们这样做时,我们没有意识到我们也需要指定安全,并且尽管我仍然不确定缺乏安全如何导致我们观察到的特定行为,所以更新会话cookie以使用{{1} }似乎已修复它,Chrome现在可以从第一个请求中识别ASP.NET_SessionId。

请注意,由于我们的.NET版本太旧了,因此我们在https://www.coderfrontline.com/chromes-samesite-cookie-changes-are-breaking-apps/找到的应用程序配置中使用了重写,现在我再次看到它完全表明要使用Secure,但在时间我们没有注意到,只是逐字复制了样本。因此,如果您使用的是HTTPS,请确保添加安全。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...