未提供所需的防伪标记或者无效

问题描述:

使用MVC 3进行操作并且所有设置都从我所能看到的正确设置。未提供所需的防伪标记或者无效

用户Authenticates使用AntiForgery Token提交表单并且一切正常。

这就是除非用户已经将表单提交打开并且在那段时间内用户登录已经过期。

当用户提交他们不再验证,他们应该被带回登录页面的形式。 (这确实发生了一些次)

相反例外“A需要防伪标志没有被提供或者是无效的。”被抛出。我想它会被抛出,因为加密的令牌包含了一些用户细节,这些细节由于用户不再被验证而无法验证。

唯一的例外是正确的,但不应该被抛出的页面应该跃升回到登录屏幕,真正的问题是用户从一个开放的形式走开了,他的登录超时。

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

我看到很多人似乎都有这个问题,但没有解决方案即将到来。

这是MVC本身的问题吗?

机器密钥设置和东西都是正确的,所以不是问题。

+0

防伪的东西实际上发生在'System.Web.WebPages',而不是MVC。所以你会想看看这个来源,而不是MVC。 – 2011-12-21 14:22:49

+0

我不确定AntiForgeryToken与用户有什么关系,因为它可以在不考虑授权的情况下使用。这可能与时间有关。 – stevethethread 2012-07-12 14:31:16

我在这里增加一个更好的答案,因为这是如此的痛苦,并回答了所有我想我会加我目前工作的解决方案在网络较差。

基本上(忽略各种选项),AntiForgeryToken通过添加一个会话cookie,然后在通过使用[ValidateAntiForgeryToken]属性装饰控制器发布表单时读取该会话cookie。

首先,在我们将任何东西修理为常规之前,请始终执行以下操作。

  1. 在web.config中创建一个machineKey,如下所示。

    <machineKey validationKey="YOUR_KEY" decryptionKey="YOUR_KEY" validation="SHA1" decryption="AES" />

    **注SHA1这就是这是不是真的很安全了,但另一个讨论**

    谷歌<machineKey> Generator和配置。

    http://msdn.microsoft.com/en-us/library/w8h3skw9%28v=vs.100%29.aspx

  2. 变化从“__RequestVerificationToken”默认的Cookie名称之一,将 不会被其他应用程序使用。 (我总是使用GUID)。

    此功能是AntiForgeryConfig.CookieName = "YOUR_NAME";

  3. 创建新的自定义属性。

此错误似乎无缘无故地出现的原因是该cookie仅适用于会话的生命周期。出于各种原因,但主要是人们离开页面这一事实打开了非常非常非常长的时间,会话超时。由于会话超时,cookie不再有效。

另一个问题是,如果您在发布到控制器上有[Authorize]属性,那么在检查通过身份验证的人之前,事务流将触发HttpAntiForgeryException。 (当会话过期时,大多数基于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和高速缓存。即使在更改代码后,您仍然可以获取错误,直到您为每个用户完成此操作。

很明显,人们有着完全不同的需求,但希望这可以给出足够的建议来控制这个非常常见和烦人的问题。

如果有人看到任何有助于或可以添加的东西,请做。

在你的行动将以上[ValidateAntiForgeryToken]属性[Authorize]属性。它们从上到下按顺序执行。所以,它应该击中授权并且看到你不再被认证。

+0

属性不能保证按您写入的顺序进行检索,是吗? – 2011-12-21 16:20:43

+0

Ryand.Johnson,虽然这应该不会真的导致问题 – 2011-12-21 16:40:46

这样做的原因似乎是,在一些大型组织的人离开自己的机器上开启无无关闭它们的一个非常非常长的时间重新启动和浏览器开启。有时甚至几个星期结束。

如果本机键在以后的日子已添加或更改,没有被关闭或已关闭了浏览器的机器都造成这种错误的人。一旦每台计算机重新启动或浏览器关闭,错误将会停止。

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

谷歌:机器密钥生成

+4

已经是这种情况我不知道为什么这已被投票。这正是导致我们遇到问题的原因,一旦添加了机器密钥并且所有机器都已重新启动,问题就不再发生。 – 2012-08-14 12:32:11