2014-12-03 61 views
1

我有一個WPF(可能是任何winform我猜)嘗試登錄到標準的MVC 5網站使用HttpClient提供AntiForgery令牌與System.Net.Http.HttpClient和MVC

Normally I can login successfully with a call to PostAsync() where I provide the UserName and Password params in a HttpContent!

然而,當我加入[ValidateAntiForgeryToken]到我的控制器的登錄(POST)動作,PostAsync()調用失敗,內部服務器錯誤。

我試圖從一個簡單的GET請求收集「__RequestVerificationToken」,並通過將其添加到POST參數,可以請求的報頭或所述的HttpHandler的的CookieContainer(或三者的任意組合與我的POST請求發送它)但仍然從服務器收到錯誤500。

我知道這可以用HttpWebRequests(apparently)完成,但我不知道我在使用HttpClient時丟失了什麼。我也不知道服務器端發生了什麼錯誤,或者如何檢查,因爲代碼永遠不會達到我的控制器方法。

其他人試過這個嗎?

EDIT 1

我添加由瀏覽器爲GET和POST發送的原始數據:

GET http://localhost:57457/Account/Login HTTP/1.1 
Accept: text/html, application/xhtml+xml, */* 
Referer: http://localhost:57457/Account/Login 
Accept-Language: en-US 
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko 
Accept-Encoding: gzip, deflate 
Connection: Keep-Alive 
DNT: 1 
Host: localhost:57457 
Cookie: NavigationTreeViewState=%5b%7b%27N0_1%27%3a%27T%27%2c%27N0%27%3a%27T%27%7d%2c%27N0_1_2%27%2c%7b%7d%5d; style=default; __RequestVerificationToken=Bak42Ga5sHJitYlmut6OgvmqXNmP7kKQRNaMSsLMAUh86iHGGmz5pnNfz_soKu46Wax9sG23arPOTnSh1bvaWyWqQ9NH4GJxFmendW8VFTg1 

RESPONSE: 
HTTP/1.1 200 OK 
Cache-Control: private 
Content-Type: text/html; charset=utf-8 
Content-Encoding: gzip 
Vary: Accept-Encoding 
Server: Microsoft-IIS/8.0 
X-AspNetMvc-Version: 5.2 
X-Frame-Options: SAMEORIGIN 
X-AspNet-Version: 4.0.30319 
X-SourceFiles: =?UTF-8?B?RDpcRUJTLkNvZGVcUHJvamVjdHNcQ1ZSUE9TX1dlYlNpdGVcQ1ZSUE9TX1dlYlNpdGVcQWNjb3VudFxMb2dpbg==?= 
X-Powered-By: ASP.NET 
Date: Thu, 04 Dec 2014 10:00:00 GMT 
Content-Length: 1734 
[View page content] 

POST http://localhost:57457/Account/Login HTTP/1.1 
Accept: text/html, application/xhtml+xml, */* 
Referer: http://localhost:57457/Account/Login 
Accept-Language: en-US 
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko 
Content-Type: application/x-www-form-urlencoded 
Accept-Encoding: gzip, deflate 
Connection: Keep-Alive 
Content-Length: 180 
DNT: 1 
Host: localhost:57457 
Pragma: no-cache 
Cookie: NavigationTreeViewState=%5b%7b%27N0_1%27%3a%27T%27%2c%27N0%27%3a%27T%27%7d%2c%27N0_1_2%27%2c%7b%7d%5d; style=default; __RequestVerificationToken=Bak42Ga5sHJitYlmut6OgvmqXNmP7kKQRNaMSsLMAUh86iHGGmz5pnNfz_soKu46Wax9sG23arPOTnSh1bvaWyWqQ9NH4GJxFmendW8VFTg1 

__RequestVerificationToken=Bak42Ga5sHJitYlmut6OgvmqXNmP7kKQRNaMSsLMAUh86iHGGmz5pnNfz_soKu46Wax9sG23arPOTnSh1bvaWyWqQ9NH4GJxFmendW8VFTg1&UserName=test&Password=test 

RESPONSE: 
HTTP/1.1 400 Bad request (user/password for testing purposes only) 
Cache-Control: private 
Content-Type: text/html; charset=utf-8 
Server: Microsoft-IIS/8.0 
X-AspNetMvc-Version: 5.2 
X-Frame-Options: SAMEORIGIN 
X-AspNet-Version: 4.0.30319 
X-SourceFiles: =?UTF-8?B?RDpcRUJTLkNvZGVcUHJvamVjdHNcQ1ZSUE9TX1dlYlNpdGVcQ1ZSUE9TX1dlYlNpdGVcQWNjb3VudFxMb2dpbg==?= 
X-Powered-By: ASP.NET 
Date: Thu, 04 Dec 2014 10:00:00 GMT 
Content-Length: 4434 
[View page content] 

編輯2

這是我的應用程序發送的GET和POST:

GET http://localhost:57457/Account/Login HTTP/1.1 
Host: localhost:57457 
Connection: Keep-Alive 

POST http://localhost:57457/Account/Login HTTP/1.1 
Content-Type: application/x-www-form-urlencoded 
Host: localhost:57457 
Cookie: __RequestVerificationToken=df9nBSP_J1IiLrv84RwrkmvbYBrnH4iqv97wRvz6HMPLWBhgI4XzGeAFcschovHwD8mTtHU6xrmVxz1Ku96_BaoB79le_vLTcrgGemU4gjc1 
Content-Length: 163 
Expect: 100-continue 

__RequestVerificationToken=df9nBSP_J1IiLrv84RwrkmvbYBrnH4iqv97wRvz6HMPLWBhgI4XzGeAFcschovHwD8mTtHU6xrmVxz1Ku96_BaoB79le_vLTcrgGemU4gjc1&UserName=test&Password=test 

最後是這樣的錯誤:

[HttpAntiForgeryException(0X80004005):提供的防僞標記驗證失敗。該Cookie " __RequestVerificationToken "和表單字段" __RequestVerificationToken "被交換。]

謝謝!

+0

你也可以發佈原始http響應 – 2014-12-04 09:47:26

+0

只是標題btw – 2014-12-04 09:49:27

回答

1

你D可能需要包括ASPNET會話cookie您的要求

編輯: 確定你是對的,它不是會話ID,但你需要兩個令牌傳送回您的文章的行動。

我認爲你做錯了什麼是兩個令牌使用相同的值,但它們應該是不同的,這兩個令牌的名稱都是__RequestVerificationToken。 從cookie中抓取的令牌應該作爲cookie返回,從表單字段中抓取的令牌將作爲表單字段返回。

+0

謝謝,但我不認爲這種情況。這真的沒有任何意義,除此之外,當我沒有[ValidateAntiForgeryToken]登錄時,我沒有傳遞任何會話ID,它工作得很好。 – raptor 2014-12-03 18:40:06

+0

據我所知,生成的僞造令牌綁定到會話值,出於安全原因停留在服務器上,所以請求令牌,然後在登錄過程中進行驗證,應該發生在同一會話中。 – 2014-12-03 21:51:32

+0

就服務器而言,一切都發生在同一個會話中。話雖如此,我肯定懷疑會議與此有關(你可以從我的編輯看到瀏覽器正在使用什麼數據/ cookies)的事實 – raptor 2014-12-03 22:38:28

0

這是因爲您在應用程序中的POST中缺少來自HtmlHelper.AntiForgeryToken()的反僞造令牌。

您需要在視圖中從您的WPF應用程序加載HtmlHelper.AntiForgeryToken()的頁面。然後獲取名稱爲__RequestVerificationToken的隱藏輸入元素的值,並將其附加到您對服務器的登錄POST請求。

+0

對不起,我從我的問題中忽略了這些信息,但我也嘗試過:我發出了一個GET請求,將__RequestVerificationToken挖出並將其添加到所有我能想到的地方:後綴參數(模擬隱藏的瀏覽器字段),請求頭(因爲我看到瀏覽器也是這樣做的)和cookie(因爲我的第一個GET請求放在那裏)。可悲的是,他們沒有任何組合沒有工作。 – raptor 2014-12-03 21:32:58

+0

@raptor你有沒有嘗試過使用Fiddler來檢查一個真正的登錄請求,然後看看你的應用程序提交? – 2014-12-03 21:37:38

+0

我很抱歉,但我不知道如何使用小提琴來監控應用程序。當我使用應用程序登錄時,它不顯示任何流量。現在,我向問題中添加了從瀏覽器獲得的數據,我將研究如何(或者如果)我可以使用提琴手實際監控應用程序,並返回我的發現。 – raptor 2014-12-03 22:27:20

相關問題