我在这里添加了一个更好的答案,因为这太痛苦了,而且整个网络上的答案都很糟糕,我想我会添加我目前工作的解决方案。
从根本上说(忽略各种选项),AntiForgeryToken 的工作原理是添加一个会话 cookie,然后在表单发布时通过使用 [ValidateAntiForgeryToken] 属性装饰控制器来读取该 cookie。
首先,在我们作为一般规则进行任何修复之前,请始终执行以下操作。
在 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
将默认 cookie 名称从“__RequestVerificationToken”更改为不会被其他应用程序使用的名称。(我总是使用 GUID)。
这样做AntiForgeryConfig.CookieName = "YOUR_NAME";
创建一个新的自定义属性。
此错误似乎无缘无故出现的原因是 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 和缓存。即使在更改代码之后,您仍然可能会收到错误,直到您为每个用户完成此操作。
显然,人们有完全不同的需求,但希望这能提供足够的建议来控制这个非常常见和烦人的问题。
如果有人看到任何可以帮助或可以添加的内容,请执行。