【问题标题】:What mistake could cause error: A required anti-forgery token was not supplied or was invalid什么错误可能导致错误:未提供所需的防伪令牌或无效
【发布时间】:2012-02-19 08:06:52
【问题描述】:

我的问题和这个问题很相似:AntiForgery Exception: A required anti-forgery token was not supplied or was invalid 但我已经安装了 MVC3,并且我使用的是 Razor。

控制器有

[ValidateAntiForgeryToken]

指定

在 html 中使用@Html.AntiForgeryToken() 打印<input name="__RequestVerificationToken"...

我还观察到,如果我在浏览器中删除了授权 cookie,并且控制器方法没有 [Authorize] AntiForery 没有任何问题 .为什么?

【问题讨论】:

  • 是您提交的每个表单中的@Html.AntiForgeryToken()?还是只是漂浮在页面上的某个地方?
  • 马克是正确的。确保 AntiForgeryToken 助手位于 Form 标签内。这是标准请求还是 Ajax 请求?

标签: c# asp.net .net asp.net-mvc antiforgerytoken


【解决方案1】:

检查您的 cookie 并确保您看到 requestVerificationToken cookie 设置正确。我之前遇到过这种情况,网站的 cookie 都设置为仅 SSL,我试图在本地通过常规 HTTP 运行它,所以 cookie 从未被接受,因为它是通过不安全的通道传输的。

对我来说,这意味着将 system.web/httpCookies 下 web.config 中的一行更改为 requireSSL="false"... 但如果这不是您所看到的,我仍然会查看可能的内容弄乱系统中的 cookie(例如会话重置、在某处手动清除 cookie 等)。如果您在控制器方法上正确设置了验证属性,并且仍然得到此属性,则可能是由于修改或删除了该 cookie!

编辑:此外,如果您在控制器上而不是仅在 POST 方法上拥有此功能,这就是为什么...这仅适用于向服务器发送 POST。

这是一个简单的自定义版本,您可以将其应用于将自动验证所有 POST 操作方法的表单:

/// <summary>
/// Custom Implementation of the Validate Anti Forgery Token Attribute.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class CustomValidateAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter
{
    /// <summary>
    /// The ValidateAntiForgeryTokenAttribute.
    /// </summary>
    private readonly ValidateAntiForgeryTokenAttribute _validator;

    /// <summary>
    /// The AcceptVerbsAttribute.
    /// </summary>
    private readonly AcceptVerbsAttribute _verbs;

    /// <summary>
    /// Initializes a new instance of the <see cref="CustomValidateAntiForgeryTokenAttribute"/> class.
    /// </summary>
    /// <param name="verbs">The verbs.</param>
    public CustomValidateAntiForgeryTokenAttribute(HttpVerbs verbs) : this(verbs, null)
    {
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="CustomValidateAntiForgeryTokenAttribute"/> class.
    /// </summary>
    /// <param name="verbs">The verbs.</param>
    /// <param name="salt">The salt.</param>
    public CustomValidateAntiForgeryTokenAttribute(HttpVerbs verbs, string salt)
    {
        _verbs = new AcceptVerbsAttribute(verbs);
        _validator = new ValidateAntiForgeryTokenAttribute
                         {
                             Salt = salt
                         };
    }

    /// <summary>
    /// Called when authorization is required.
    /// </summary>
    /// <param name="filterContext">The filter context.</param>
    public void OnAuthorization(AuthorizationContext filterContext)
    {
        var httpMethodOverride = filterContext.HttpContext.Request.GetHttpMethodOverride();

        var found = false;
        foreach (var verb in _verbs.Verbs)
        {
            if (verb.Equals(httpMethodOverride, StringComparison.OrdinalIgnoreCase))
            {
                found = true;
            }
        }

        if (found && !filterContext.RequestContext.RouteData.Values["action"].ToString().StartsWith("Json"))
        {
            _validator.OnAuthorization(filterContext);
        }
    }
}

然后您可以将以下内容添加到您的所有控制器中,或者如果您覆盖并继承自一个控制器,则添加到您的基本控制器中:

    [CustomValidateAntiForgeryToken(HttpVerbs.Post)]

【讨论】:

    【解决方案2】:

    防伪令牌与用户身份相关联。如果您在生成和验证令牌之间更改当前登录的用户身份,则令牌将无法成功验证。此外,这也解释了为什么在匿名模式下一切都为您工作。

    【讨论】:

      猜你喜欢
      • 2011-02-16
      • 2012-01-25
      • 1970-01-01
      • 2012-06-09
      • 2013-01-27
      • 1970-01-01
      • 2011-09-01
      • 2014-03-07
      相关资源
      最近更新 更多