我有一个 MVC 3.0 应用程序。在生产中,我们随机收到一个异常,提示“未提供所需的防伪令牌或无效”。这不会发生在每个用户身上,因此可以肯定地说防伪令牌过程设置正确。但是,某些用户每次登录我们的网站时都会发生这种情况。他们登录,单击生成正在验证的帖子的链接,验证失败,他们得到我们的错误页面,他们点击返回,再次发布,一切都很好。
我完全不知道发生了什么。
我查看了 MVC 源代码,发现有几个地方会抛出描述为“未提供所需的防伪令牌或无效”的异常。第一个是在 AntiForgeryDataSerializer.cs 中反序列化令牌时。不过,这不是我们的问题所在,因为在这种情况下,抛出异常并带有描述实际序列化问题的内部异常。我们正在记录内部异常,在这种情况下我们没有记录。
引发此异常的另一个地方是 AntiForgeryWorker.cs 中的 Validate 方法。在这里,异常是在没有内部异常的情况下引发的,所以问题一定出在这段代码的某个地方。它看起来像这样:
public void Validate(HttpContextBase context, string salt) {
Debug.Assert(context != null);
string fieldName = AntiForgeryData.GetAntiForgeryTokenName(null);
string cookieName = AntiForgeryData.GetAntiForgeryTokenName(context.Request.ApplicationPath);
HttpCookie cookie = context.Request.Cookies[cookieName];
if (cookie == null || String.IsNullOrEmpty(cookie.Value)) {
// error: cookie token is missing
throw CreateValidationException();
}
AntiForgeryData cookieToken = Serializer.Deserialize(cookie.Value);
string formValue = context.Request.Form[fieldName];
if (String.IsNullOrEmpty(formValue)) {
// error: form token is missing
throw CreateValidationException();
}
AntiForgeryData formToken = Serializer.Deserialize(formValue);
if (!String.Equals(cookieToken.Value, formToken.Value, StringComparison.Ordinal)) {
// error: form token does not match cookie token
throw CreateValidationException();
}
string currentUsername = AntiForgeryData.GetUsername(context.User);
if (!String.Equals(formToken.Username, currentUsername, StringComparison.OrdinalIgnoreCase)) {
// error: form token is not valid for this user
// (don't care about cookie token)
throw CreateValidationException();
}
if (!String.Equals(salt ?? String.Empty, formToken.Salt, StringComparison.Ordinal)) {
// error: custom validation failed
throw CreateValidationException();
}
}
其中之一是抛出异常。我没有使用盐,所以会扔掉最后一个。我查看了 IIS 日志,我看到了 cookie,并不是 cookie 丢失了。因此,要么缺少表单值(我认为不太可能),要么值不匹配,要么用户名不匹配。我不知所措。我无法重现这个,所以我真的无法调试。这似乎一遍又一遍地发生在同一个用户身上,但我无法想出他们正在做什么的模式。他们必须启用 cookie 才能登录我们的网站才能达到这一点,所以这不是问题。用户将在 8-10 秒内登录、发布表单并收到错误消息。然后他们似乎在看到我们的错误页面后点击了返回按钮,再次尝试发布,这很好。
关于下一步如何进行的任何想法?