背景
我有一个相对较新的ASP.NET Core 2网站。它运行在一台服务器上(Windows Server 2012 R2,IIS 8.5),每当我上传更新时,我只会在几天后重新启动该网站。大约每天都会由于反伪造系统的拒绝而导致用户请求失败。这些是POST请求,并没有什么特别之处。我在POST请求中包含了反伪造值,99%的时间,POST请求都能正常工作。但是当它们不起作用时,stdout日志会显示“Antiforgery token validation failed. The antiforgery cookie token and request token do not match.” 当我使用该确切语句进行Web搜索时,我得到零结果。因此,我转向Stack Overflow寻求帮助。[现在这个问题已经不再是真实的,因为Web搜索现在可以得到这个Stack Overflow问题。]
错误
下面是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.'.
对于产生上述标准输出的请求,
IAntiforgery.IsRequestValidAsync
返回 false。请注意错误消息“防伪令牌 cookie 和请求令牌不匹配。”以下是一个失败的 POST 请求和相关 cookie 的简化示例。
Cookie: .AspNetCore.Antiforgery.ClRyCRmWApY=CfDJ8F9Fs4CqDFpLttT96eZw9WFtJht41WcNrmgshi2pFGwcxhr0_0hvINQc7Yl9Cbjhv-TiSNXeEctyKborLI49AcjHfWIgOmmKkbjOe7QMn8Z0WZtkQy5JcaBHKEGTu1p-La8JL8pZZqZy02Hrswpkh3I
我还在请求失败并使用一些错误处理中间件后多次捕获到这个数据:
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.RequestToken
,所以这可能与此有关。
Github上的ASP.NET Core 2
我决定查看ASP.NET Core 2的源代码。我发现了这个文件,特别是第145行:
这行代码从第134行开始读取文件,获取了消息“防伪cookie令牌和请求令牌不匹配。”
https://github.com/aspnet/Antiforgery/blob/dev/src/Microsoft.AspNetCore.Antiforgery/Resources.resx
所以我认为消息是从那里发起的,但我仍然想知道为什么会发生这种情况。
问题
请有经验的人帮助我解决这些防伪令牌无法验证的问题?用户的Web浏览器是否可能会破坏cookie或POST数据?有没有任何建议?谢谢。