Asp.net-Mvc

RequestVerificationToken 不匹配

  • October 14, 2011

我對反 CRSF MVC 機制有疑問。返回的 cookie 和表單輸入不匹配。我每次都收到錯誤,僅在一個特定頁面中。在應用程序的其餘部分中,它執行良好。

伺服器正在返回HTTP 500 Internal Server Error,我可以在日誌中看到這個異常:

[System.Web.Mvc.HttpAntiForgeryException]:{“未提供所需的防偽令牌或無效。”}

這是伺服器生成的隱藏輸入:

<input name="__RequestVerificationToken" type="hidden" value="QK8P7rjyZE6Vm5seY7Fr704YCOoFGdTIMzl1W7R0ZFpXSMjGKLG2T05DfFSYTxvtQCEx7DDT69DGsDB2+ZXFHY8oAjiKz0gw8BhDFywgmfIpoXnGpj7fONNzIIfvbrDrE9WJsMu6Io/0bDLM5WfKs0zktiNjyOWpfYrmnfINYmjW8NLOZFoz74xTcgTptAld">

這是返回的 Cookie:

Set-Cookie:__RequestVerificationToken_L2VGbG93=skmTAVI8HCbfxDS+xhioIMIISL3UOBI7qJM1JbHjTtAqKl4W70pDUcTKMm0p3R3mrHDziE8vXw0C0OO4HArzWO1/e6py+v/cFdbe9maFgjl4jMiZ9Wc4YIhC6+IUXkk6yqJDJ8dCIr8qtGaYcD9IX+m7/SlVhu521KQSWJYRcaY=; path=/; HttpOnly

當我檢查伺服器發送的內容時,cookie 完全相同,但我認為有效負載具有不同的編碼:

__RequestVerificationToken:QK8P7rjyZE6Vm5seY7Fr704YCOoFGdTIMzl1W7R0ZFpXSMjGKLG2T05DfFSYTxvtQCEx7DDT69DGsDB2%2BZXFHY8oAjiKz0gw8BhDFywgmfIpoXnGpj7fONNzIIfvbrDrE9WJsMu6Io%2F0bDLM5WfKs0zktiNjyOWpfYrmnfINYmjW8NLOZFoz74xTcgTptAld

區別在於出現編碼的兩個字元:

   /    ->   %2F  
   +    ->   %2B

這些是我能找到的隱藏輸入欄位和後有效載荷之間的唯一區別。

ValidateAntiForgeryToken導致驗證令牌失敗的問題可能是什麼?

問候。

我最近遇到並解決了幾個問題ValidateAntiForgeryToken,所以我將與您分享我的發現。

Salt:由於您提到這只發生在單個頁面上,我最好的猜測是您在呼叫和呼叫中使用了不同salt的值。Html.AntiForgeryToken(salt)``ValidateAntiForgeryToken(salt)

AJAX:正如另一個答案所說,使用 AJAX 可能需要額外的工作以確保令牌包含在 POST 中。這是我最喜歡的將令牌添加到所有 AJAX POST 請求的簡單、自動的解決方案

不過,在您的問題中,您聲明您已驗證令牌正在發送。您是否驗證過您只發送一次令牌?我發現我的 AJAX 呼叫發送了兩次令牌,合併了這些值,並導致它失敗。

Machine Key and Cookies:這個問題很醜陋,很容易發現(導致異常),但不是很直覺。驗證 cookie 和令牌使用唯一的“機器密鑰”進行編碼和解碼。這意味著如果您有伺服器場,或更改您的伺服器,您的 cookie 將不再有效。關閉瀏覽器可以解決問題(因為 cookie 是會話 cookie)。但是,有些人會讓他們的瀏覽器視窗在後台打開很長時間!

解決方案是在配置文件中設置“機器密鑰”。這將告訴 MVC 在所有伺服器上使用相同的密鑰,確保 cookie 在任何地方都可以解密。

編碼錯誤:使用名為 jMeter 的測試實用程序,我們嘗試對我們的頁面進行負載測試,但發現它有一個錯誤導致我們的令牌"在值周圍有 2 個額外的值。

解決方案是降低您對工具的信任!在瀏覽器中進行測試,如果可行,則創建一個提取令牌和 cookie 值的測試,並設置斷點以驗證結果。

如果這些東西都不適合您,那麼我建議您查看MVC 原始碼ValidateAntiForgeryTokenAttribute,特別是OnAuthorization方法。它將幫助您查看驗證可能失敗的不同步驟。您甚至可以檢查您的錯誤Exception.StackTrace以確定哪個部分出現故障。

作為旁注,我真的不喜歡ValidateAntiForgeryToken在 MVC 中的實現,因為:

  • 大約有 5 個驗證步驟可能會失敗,但只有一個通用錯誤消息。
  • 該類是密封的,因此無法使用其他功能對其進行擴展。
  • 加密方法很奇怪——它初始化 aPage並創建一個人工ViewState來加密令牌和 cookie。似乎矯枉過正。

因此,我獲取了原始碼,並創建了自己的專門子類,結果證明這對調試它的問題也很有幫助,因為我可以在驗證方法上設置斷點,並且很容易確定哪個驗證步驟失敗了.

引用自:https://stackoverflow.com/questions/7766975