MVC防伪代码验证 - 随机错误

时间:2013-01-30 17:41:35

标签: asp.net asp.net-mvc-3

我有一个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秒的范围内登录,进行表单发布并获取错误。在看到我们的错误页面之后,他们似乎会点击后退按钮,再次尝试发布,这很好。

关于如何进行下一步的任何想法?

0 个答案:

没有答案