提供带有System.Net.Http.HttpClient和MVC的AntiForgery令牌 [英] Provide AntiForgery Token with System.Net.Http.HttpClient and MVC

查看:77
本文介绍了提供带有System.Net.Http.HttpClient和MVC的AntiForgery令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个WPF(我猜可能是winform)应用程序,该应用程序尝试使用 HttpClient 登录到标准MVC 5网站.

I have a WPF (could be any winform I guess) app that tries to login to a standard MVC 5 website using a HttpClient.

通常,我可以通过调用 PostAsync()成功登录,在此我可以在 HttpContent 中提供UserName和Password参数!

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

但是,当我在控制器的登录(POST)操作中添加 [ValidateAntiForgeryToken] 时,PostAsync()调用会失败,并出现内部服务器错误.

However, when I add the [ValidateAntiForgeryToken] to my controller's Login (POST) action, the PostAsync() call fails with Internal Server Error.

我尝试从简单的GET请求中收集"__RequestVerificationToken",并将其与POST请求一起发送,方法是将其添加到POST参数,请求的标题或HttpHandler的 CookieContainer (或任何其他方法)中三者的结合),但仍然从服务器收到错误500.

I have tried collecting the "__RequestVerificationToken" from a simple GET request and sending it with my POST request by adding it to the POST params, the Header of the request or the HttpHandler's CookieContainer (or any combination of the three) but still I get error 500 from the server.

我知道这可以通过HttpWebRequests完成(显然)但是我不知道使用HttpClient时缺少什么.我也不知道服务器端到底出了什么问题..或者因为代码永远无法到达我的控制器方法,所以该如何检查.

I know it can be done with HttpWebRequests (apparently) but I don't know what I'm missing when using a HttpClient. I also don't know what exactly went wrong on the server side.. or how to check that since the code never reaches my controller method.

其他人有没有尝试过这个?

Did someone else try this by any chance?

编辑1 :

我正在添加浏览器发送的GET和POST原始数据:

I'm adding the raw data sent by the browser for both GET and 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内容:

This is what my app sends for GET and 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"被交换了.]

谢谢!

推荐答案

您可能需要在请求中包含aspnet会话ID cookie

You d probably need to include aspnet session id cookie with your requests

好的,这不是会话ID,但是您需要两个令牌才能发回您的帖子操作.

OK ur right, it is not the session id, but you need two token to send back to your post action.

我认为您做错了两个令牌使用相同的值,但是它们应该不同,两个令牌的名称均为__RequestVerificationToken.从Cookie抓取的令牌应作为cookie发送回去,从表单字段抓取的令牌应作为表单字段退回.

I think what you re doing wrong is using same value for both tokens, but they should be different, altho name of both tokens is __RequestVerificationToken. Token grabbed from cookie should be send back as cookie and token grabbed from form field goes back as form field.

这篇关于提供带有System.Net.Http.HttpClient和MVC的AntiForgery令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆