Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 未提供所需的防伪令牌或该令牌无效_C#_Asp.net Mvc_Model View Controller_Antiforgerytoken - Fatal编程技术网

C# 未提供所需的防伪令牌或该令牌无效

C# 未提供所需的防伪令牌或该令牌无效,c#,asp.net-mvc,model-view-controller,antiforgerytoken,C#,Asp.net Mvc,Model View Controller,Antiforgerytoken,我使用的是MVC3,从我所看到的一切都设置正确 用户通过身份验证提交带有AntiForgery令牌的表单,一切正常 除非用户将要提交的表单保持打开状态,并且在该时间内用户登录已过期 当用户提交表单时,由于他们不再经过身份验证,应将其带回登录页面。(这种情况有时会发生) 而是引发异常“未提供所需的防伪令牌或该令牌无效”。我想象它被抛出是因为加密令牌包含一些用户详细信息,这些信息无法验证,因为用户不再经过身份验证 异常是正确的,但不应被抛出,因为页面应跳回登录屏幕,因为真正的问题是用户离开打开的表单

我使用的是MVC3,从我所看到的一切都设置正确

用户通过身份验证提交带有AntiForgery令牌的表单,一切正常

除非用户将要提交的表单保持打开状态,并且在该时间内用户登录已过期

当用户提交表单时,由于他们不再经过身份验证,应将其带回登录页面。(这种情况有时会发生)

而是引发异常“未提供所需的防伪令牌或该令牌无效”。我想象它被抛出是因为加密令牌包含一些用户详细信息,这些信息无法验证,因为用户不再经过身份验证

异常是正确的,但不应被抛出,因为页面应跳回登录屏幕,因为真正的问题是用户离开打开的表单并且登录超时

这个问题很难复制,因为它并不总是这样

我看到很多人似乎有这个问题,但没有解决办法

这是MVC本身的问题吗


机器密钥设置和内容都是正确的,因此这不是问题。

在您的操作中将
[Authorize]
属性置于
[ValidateAntiForgeryToken]
属性之上。它们按自上而下的顺序执行。因此,它应该点击“授权”按钮,然后看到您不再经过身份验证。

原因似乎是在某些大型组织中,人们在不重新启动的情况下打开机器,在很长一段时间内不关闭浏览器而打开浏览器。有时甚至连续几周

如果在以后添加或更改了机器密钥,则未关闭或关闭浏览器的机器是导致此错误的机器。一旦每台机器重新启动或浏览器关闭,错误将停止

注意:要停止此错误,创建机器密钥也很重要


Google:machine key generator

我在这里添加了一个更好的答案,因为这是一个非常痛苦的问题,而且在整个网络上都没有得到很好的回答。我想我会添加我目前正在使用的解决方案

从根本上说(忽略各种选项),AntiForgeryToken的工作原理是添加会话cookie,然后在发布表单时通过使用[ValidateAntiForgeryToken]属性装饰控制器来读取会话cookie

[AttributeUsage( AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true )]
  public class CustomValidateAntiForgeryToken : FilterAttribute, IAuthorizationFilter {

    public void OnAuthorization( AuthorizationContext filterContext ) {

      if ( filterContext == null ) {
        throw new ArgumentNullException( "filterContext" );
      }

      try {
        AntiForgery.Validate();
      }
      catch {

        // Here do whatever is you wish 
        // you could just re throw the error or what ever.

        // In this case I have redirected to a Signout

        filterContext.Result = new RedirectToRouteResult( 
          new RouteValueDictionary( 
            new {
              action     = "Sign_Out",
              controller = "SOME_CONTROLLER",
              area       = ""
            } 
          )
        );

      }

    }

  }
首先,作为一般规则,在我们开始修复任何东西之前,请始终执行以下操作

  • 在web.config中创建machineKey,如下所示

    **注1:这不再是非常安全的,但这是另一个讨论**

    谷歌
    Generator
    并进行配置

  • 将默认cookie名称从“\uu RequestVerificationToken”更改为 不能被其他应用程序使用。(我总是使用GUID)

    使用
    AntiForgeryConfig.CookieName=“您的名字”执行此操作

  • 创建新的自定义属性

  • [AttributeUsage( AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true )]
      public class CustomValidateAntiForgeryToken : FilterAttribute, IAuthorizationFilter {
    
        public void OnAuthorization( AuthorizationContext filterContext ) {
    
          if ( filterContext == null ) {
            throw new ArgumentNullException( "filterContext" );
          }
    
          try {
            AntiForgery.Validate();
          }
          catch {
    
            // Here do whatever is you wish 
            // you could just re throw the error or what ever.
    
            // In this case I have redirected to a Signout
    
            filterContext.Result = new RedirectToRouteResult( 
              new RouteValueDictionary( 
                new {
                  action     = "Sign_Out",
                  controller = "SOME_CONTROLLER",
                  area       = ""
                } 
              )
            );
    
          }
    
        }
    
      }
    
    此错误似乎无缘无故出现的原因是cookie仅在会话的生命周期内有效。出于各种原因,但主要是因为人们会在会话超时后将页面打开很长一段时间。由于会话已超时,cookie不再有效

    另一个问题是,如果posted to控制器上有[Authority]属性,那么在检查谁经过身份验证之前,事件流将触发HttpAntiforyException。(在大多数基于cookie的身份验证中,当会话过期时,用户不再进行身份验证)

    解决此问题的方法是创建自定义[CustomValidateAntiForgeryToken]属性

    [AttributeUsage( AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true )]
      public class CustomValidateAntiForgeryToken : FilterAttribute, IAuthorizationFilter {
    
        public void OnAuthorization( AuthorizationContext filterContext ) {
    
          if ( filterContext == null ) {
            throw new ArgumentNullException( "filterContext" );
          }
    
          try {
            AntiForgery.Validate();
          }
          catch {
    
            // Here do whatever is you wish 
            // you could just re throw the error or what ever.
    
            // In this case I have redirected to a Signout
    
            filterContext.Result = new RedirectToRouteResult( 
              new RouteValueDictionary( 
                new {
                  action     = "Sign_Out",
                  controller = "SOME_CONTROLLER",
                  area       = ""
                } 
              )
            );
    
          }
    
        }
    
      }
    
    最后,如果您在任何当前活动的系统中更改了这些内容,请确保每个人都注销,关闭浏览器,甚至在可能的情况下重新启动,并清除cookie和缓存。即使更改了代码,在为每个用户执行此操作之前,仍然可能会出现错误

    显然,人们有着完全不同的需求,但希望这能提供足够的建议来控制这个非常常见和恼人的问题


    如果有人看到任何有帮助或可以添加的内容,请执行。

    防伪工作实际上发生在
    System.Web.WebPages
    ,而不是MVC中。因此,您可能希望查看该来源,而不是MVC。我不确定AntiForgeryToken是否与用户有关,因为它可以在未经授权的情况下使用。它可能与时间有关。属性不能保证按照您编写它们的顺序检索,是吗?Ryand.Johnson这已经是事实,但这不应该真正导致问题。我不知道为什么这被否决。这正是导致我们出现问题的原因,一旦添加了机器密钥并且所有机器都重新启动,问题就不再发生。