什么错误可能导致错误:未提供所需的防伪令牌或无效

时间:2012-01-26 06:21:05

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

我的问题与此问题非常相似:AntiForgery Exception: A required anti-forgery token was not supplied or was invalid 但我有MVC3和我使用Razor安装。

控制器有

[ValidateAntiForgeryToken]

指定

html中的

使用<input name="__RequestVerificationToken"...

打印@Html.AntiForgeryToken()

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

2 个答案:

答案 0 :(得分:0)

检查您的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)]

答案 1 :(得分:0)

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