C# 未提供所需的防伪令牌或该令牌无效
我使用的是MVC3,从我所看到的一切都设置正确 用户通过身份验证提交带有AntiForgery令牌的表单,一切正常 除非用户将要提交的表单保持打开状态,并且在该时间内用户登录已过期 当用户提交表单时,由于他们不再经过身份验证,应将其带回登录页面。(这种情况有时会发生) 而是引发异常“未提供所需的防伪令牌或该令牌无效”。我想象它被抛出是因为加密令牌包含一些用户详细信息,这些信息无法验证,因为用户不再经过身份验证 异常是正确的,但不应被抛出,因为页面应跳回登录屏幕,因为真正的问题是用户离开打开的表单并且登录超时 这个问题很难复制,因为它并不总是这样 我看到很多人似乎有这个问题,但没有解决办法 这是MVC本身的问题吗C# 未提供所需的防伪令牌或该令牌无效,c#,asp.net-mvc,model-view-controller,antiforgerytoken,C#,Asp.net Mvc,Model View Controller,Antiforgerytoken,我使用的是MVC3,从我所看到的一切都设置正确 用户通过身份验证提交带有AntiForgery令牌的表单,一切正常 除非用户将要提交的表单保持打开状态,并且在该时间内用户登录已过期 当用户提交表单时,由于他们不再经过身份验证,应将其带回登录页面。(这种情况有时会发生) 而是引发异常“未提供所需的防伪令牌或该令牌无效”。我想象它被抛出是因为加密令牌包含一些用户详细信息,这些信息无法验证,因为用户不再经过身份验证 异常是正确的,但不应被抛出,因为页面应跳回登录屏幕,因为真正的问题是用户离开打开的表单
机器密钥设置和内容都是正确的,因此这不是问题。在您的操作中将
[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 = ""
}
)
);
}
}
}
首先,作为一般规则,在我们开始修复任何东西之前,请始终执行以下操作
**注1:这不再是非常安全的,但这是另一个讨论**
谷歌Generator
并进行配置
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这已经是事实,但这不应该真正导致问题。我不知道为什么这被否决。这正是导致我们出现问题的原因,一旦添加了机器密钥并且所有机器都重新启动,问题就不再发生。