防伪令牌发出时包含当前连接用户的用户名。并且在验证其有效性时,会根据发出令牌时使用的用户检查当前连接的用户。因此,例如,如果您有一个用户尚未经过身份验证的表单,并且您发出了一个防伪令牌,则不会有任何用户名存储在其中。如果在提交表单时对用户进行身份验证,则令牌将不再有效。同样适用于注销。
下面是 Validate 方法的样子:
public void Validate(HttpContextBase context, string salt)
{
string antiForgeryTokenName = AntiForgeryData.GetAntiForgeryTokenName(null);
string str2 = AntiForgeryData.GetAntiForgeryTokenName(context.Request.ApplicationPath);
HttpCookie cookie = context.Request.Cookies[str2];
if ((cookie == null) || string.IsNullOrEmpty(cookie.Value))
{
throw CreateValidationException();
}
AntiForgeryData data = this.Serializer.Deserialize(cookie.Value);
string str3 = context.Request.Form[antiForgeryTokenName];
if (string.IsNullOrEmpty(str3))
{
throw CreateValidationException();
}
AntiForgeryData data2 = this.Serializer.Deserialize(str3);
if (!string.Equals(data.Value, data2.Value, StringComparison.Ordinal))
{
throw CreateValidationException();
}
string username = AntiForgeryData.GetUsername(context.User);
if (!string.Equals(data2.Username, username, StringComparison.OrdinalIgnoreCase))
{
throw CreateValidationException();
}
if (!string.Equals(salt ?? string.Empty, data2.Salt, StringComparison.Ordinal))
{
throw CreateValidationException();
}
}
一种可能的调试方法是从其源代码重新编译 ASP.NET MVC,并准确记录您在引发异常时输入的哪些 if 情况。