背景

我有一个相对较新的ASP.NET Core 2网站。它仅在一台服务器(Windows Server 2012 R2,IIS 8.5)上运行,并且在上载更新时,我每隔几天仅重新启动一次站点。大约每天一次,由于反伪造系统的拒绝,用户的请求失败。这些是POST请求,关于它们没有什么特别的。我将防伪造值包括在POST请求中,并且在99%的时间中,POST请求都能正常工作。但是,如果不这样做,则标准输出日志会显示:“防伪 token 验证失败。防伪cookie token 和请求 token 不匹配。”当我使用该确切语句执行Web搜索时,得到的结果为零。因此,我转向了堆栈溢出。 [这不再是正确的,因为Web搜索现在会产生此堆栈溢出问题。]

失误

我在下面包括了stdout日志的相关部分。

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 POST [domain redacted] application/x-www-form-urlencoded 234
info: Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.ValidateAntiforgeryTokenAuthorizationFilter[1]
      Antiforgery token validation failed. The antiforgery cookie token and request token do not match.
Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException: The antiforgery cookie token and request token do not match.
   at Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgery.ValidateTokens(HttpContext httpContext, AntiforgeryTokenSet antiforgeryTokenSet)
   at Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgery.<ValidateRequestAsync>d__9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.ValidateAntiforgeryTokenAuthorizationFilter.<OnAuthorizationAsync>d__3.MoveNext()
info: Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker[3]
      Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.AutoValidateAntiforgeryTokenAuthorizationFilter'.
info: Microsoft.AspNetCore.Mvc.StatusCodeResult[1]
      Executing HttpStatusCodeResult, setting HTTP status code 400
info: Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker[2]
      Executed action /Index in 2.6224ms
warn: Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgery[1]
      Antiforgery validation failed with message 'The antiforgery cookie token and request token do not match.'.

对于导致上述stdout输出的请求,IAntiforgery.IsRequestValidAsync通过返回false表示同意。注意错误消息“防伪cookie token 和请求 token 不匹配。”这是POST请求失败和相关Cookie的简化示例。
POST: __RequestVerificationToken=CfDJ8F9Fs4CqDFpLttT96eZw9WHjWfHO8Yawn35k4Yq3gDK5n1TDJDDiY5o86VQs1_qOVIYBydCizBU4knb7Jmq1-heGhwnMu2KmhUIiAd0xI7Sudv3GX-J0OI6wRfiPL4L1KRs2Pml8dbsDfwemewBqi18Cookie: .AspNetCore.Antiforgery.ClRyCRmWApY=CfDJ8F9Fs4CqDFpLttT96eZw9WFtJht41WcNrmgshi2pFGwcxhr0_0hvINQc7Yl9Cbjhv-TiSNXeEctyKborLI49AcjHfWIgOmmKkbjOe7QMn8Z0WZtkQy5JcaBHKEGTu1p-La8JL8pZZqZy02Hrswpkh3I
在请求失败并出现400错误(使用一些错误处理中间件)之后,我还捕获了几次该数据:
AntiforgeryTokenSet tokens = antiforgery.GetTokens(context);
tokens.CookieToken:  null
tokens.FormFieldName:  "__RequestVerificationToken"
tokens.HeaderName:  "RequestVerificationToken"
tokens.RequestToken:  "CfDJ8F9Fs4CqDFpLttT96eZw9WH33jSw5mM8h7RpEd3vGISQTRkx1rfwm-L2lfkvXKMBc-riESmoTo_fnIjeBbRmOo5KuJHr09f8B75sQ9g_djIVeeaGwMw5KE6W1O2-7Vi03fCnwlTv8l-BWGst76Ln-ZQ"

因此,这是三个字符串:
POST String:  "CfDJ8F9Fs4CqDFpLttT96eZw9WHjWfHO8Yawn35k4Yq3gDK5n1TDJDDiY5o86VQs1_qOVIYBydCizBU4knb7Jmq1-heGhwnMu2KmhUIiAd0xI7Sudv3GX-J0OI6wRfiPL4L1KRs2Pml8dbsDfwemewBqi18"
Cookie String:  "CfDJ8F9Fs4CqDFpLttT96eZw9WFtJht41WcNrmgshi2pFGwcxhr0_0hvINQc7Yl9Cbjhv-TiSNXeEctyKborLI49AcjHfWIgOmmKkbjOe7QMn8Z0WZtkQy5JcaBHKEGTu1p-La8JL8pZZqZy02Hrswpkh3I"
antiforgery.GetTokens(context).RequestToken:  "CfDJ8F9Fs4CqDFpLttT96eZw9WH33jSw5mM8h7RpEd3vGISQTRkx1rfwm-L2lfkvXKMBc-riESmoTo_fnIjeBbRmOo5KuJHr09f8B75sQ9g_djIVeeaGwMw5KE6W1O2-7Vi03fCnwlTv8l-BWGst76Ln-ZQ"

POST字符串和cookie字符串不匹配,但是以我的经验,即使有ASP.NET Core认为合法的请求,它们也永远不会匹配。但是奇怪的是,POST字符串和tokens.RequestToken都不匹配。我认为它们应该匹配,尽管我稍后在请求生命周期中捕获了tokens.RequestTooken,所以也许与它有关。

GitHub上的ASP.NET Core 2

我决定查看ASP.NET Core 2的源代码。我找到了此文件,尤其是第145行:

https://github.com/aspnet/Antiforgery/blob/dev/src/Microsoft.AspNetCore.Antiforgery/Internal/DefaultAntiforgeryTokenGenerator.cs

该行将收到消息“防伪Cookie token 和请求 token 不匹配。”从该文件的第134行:

https://github.com/aspnet/Antiforgery/blob/dev/src/Microsoft.AspNetCore.Antiforgery/Resources.resx

因此,我认为这就是消息的发源地,但是我仍然想知道为什么会这样。

问题

有人可以帮我弄清楚为什么这些防伪 token 没有通过验证吗?用户的Web浏览器是否有可能处理cookie或POST数据?有没有人在这方面有经验或有什么建议?谢谢你。

最佳答案

全局禁用过滤器似乎是将其关闭的唯一方法。我得到了@svallis的代码以进行视线修改:

services.AddMvc().AddRazorPagesOptions(options =>
{
    options.Conventions.ConfigureFilter(new IgnoreAntiforgeryTokenAttribute());
});

https://github.com/aspnet/Mvc/issues/7012

关于c# - 显然是随机错误: "Antiforgery token validation failed. The antiforgery cookie token and request token do not match.",我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48179720/

10-10 03:00