2017-07-18 35 views
1

我已将MVC代码从2.0版升级到4.0版。 现在,我收到以下错误: “所需的防伪令牌未提供或无效。”AntiForgeryToken无效

我添加在ValidateAntiForgeryTokenAttribute.cs下面的代码:

public void OnAuthorization(AuthorizationContext filterContext) 
    { 
     if (filterContext == null) 
     { 
      throw new ArgumentNullException("filterContext"); 
     } 

     string httpMethodOverride = filterContext.HttpContext.Request.GetHttpMethodOverride(); 
     if (!this.verbs.Verbs.Contains(httpMethodOverride, StringComparer.OrdinalIgnoreCase)) 
     { 
      return; 
     } 

     AntiForgeryDataSerializer antiForgeryDataSerializer = new AntiForgeryDataSerializer(); 
     AntiForgeryData antiForgeryData = new AntiForgeryData(); 
     string fieldName = antiForgeryData.GetAntiForgeryTokenName(null); 
     string cookieName = antiForgeryData.GetAntiForgeryTokenName(filterContext.HttpContext.Request.ApplicationPath); 


     HttpCookie cookie = filterContext.HttpContext.Request.Cookies[cookieName]; 

     if (cookie == null || String.IsNullOrEmpty(cookie.Value)) 
     { 
      throw CreateValidationException(); 
     } 

     AntiForgeryData cookieToken = antiForgeryDataSerializer.Deserialize(cookie.Value); 
     //Rest of the code here// 
     } 

在“filterContext”,cookie的名称是“_RequestVerificationToken”,然后我添加路径名。路径名称在Base64中编码并添加到AntiForgeryFieldName中,并成为“_RequestVerificationToken_Lw__”。 当我们检查cookie是否存在时,显然我们找不到它,并且我们得到AntiForgery异常。 但是在这个代码的旧版本中,“filterContext”中的Cookie值为“_RequestVerificationToken_Lw__”,因此工作正常。 那么,这里的问题在哪里?它与机器钥匙还是其他什么有关?

在此先感谢。

+2

我不完全确定我明白你在这里做什么。防伪是内置于MVC。你不需要你自己的属性;只需在您的视图中使用控制器操作中的内置'ValidationAntiForgeryToken'属性和'@ Html.AntiForgeryToken()'。 –

回答

0

@ Html.AntiForgeryToken()在调用视图生成新的令牌和在这样的形式中写道:

<form action="..." method="post">   
    <input name="__RequestVerificationToken" type="hidden"   
     value="J56khgCvbE3bVcsCSZkNVuH9Cclm9SSIT/ywruFsXEgmV8CL2eW5C/gGsQUf/YuP" /> 
     <!-- Other fields. -->  
</form> 

并且还写入到该Cookie:

__RequestVerificationToken_Lw__= 
    J56khgCvbE3bVcsCSZkNVuH9Cclm9SSIT/ywruFsXEgmV8CL2eW5C/gGsQUf/YuP 

当上面的表格被提交,它们都被发送到服务器。

在服务器端,[ValidateAntiForgeryToken]属性用于指定控制器或动作来验证他们:

[HttpPost] 
[ValidateAntiForgeryToken()] 
public ActionResult Action(/* ... */) 
{ 
    // ... 
} 

所有你需要做的就是调用AntiForgeryToken在视图中,并指定“ValidateAntiForgeryToken”控制器动作的属性。

+0

感谢您的回复。是的,我们在View中有@ html.AntiForgeryToken(),并且我们在控制器中使用了[ValidateAntiForgeryToken]属性,这就是它在问题中提供的“OnAuthorization”方法中的方式。我们一直面临的一个大问题是,“_RequestVerification_Lw__”cookie不会在MVC 4.0中为我们生成。 HttpContext.Request.Cookies只有“_RequestVerificationToken”作为cookie名称和相应的编码值。任何帮助表示赞赏。 –

+0

当我查看源时,仅生成“__RequestVerificationToken”。如果找不到cookie,可以尝试添加以下代码行以仅使用“__RequestVerificationToken”进行验证,而不是抛出“CreateValidationException”。让我知道它是否有效! AntiForgery.Validate(cookie!= null?cookie.Value:null,httpContext.Request.Headers [“__ RequestVerificationToken”]); – SailajaPalakodeti

+0

此更改引发以下错误:'/'应用程序中的服务器错误。 所需的防伪cookie“__RequestVerificationToken”不存在。 描述:执行当前Web请求期间发生未处理的异常。请查看堆栈跟踪以获取有关该错误的更多信息以及源代码的位置。 异常详细信息:System.Web.Mvc.HttpAntiForgeryException:所需的防伪cookie“__RequestVerificationToken”不存在。 –