I need to simulate Win Auth http header for HttpClient. It could be something like the following , see the Authorization header :
POST http://url HTTP/1.1
Host: http://127.0.0.1/
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0
Accept: /
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://127.0.0.1/
Content-Length: 18
Origin: http://127.0.0.1/
Connection: keep-alive
Authorization: NTLM TlRMTVNTUAADAAAAGAAYAIQAAABuAW4BnAAAAAAAAABYAAAAFgAWAFgAAAA
WABYAbgAAAAAAAAAKAgAABYKIogoAACgAAAAPUOVvBWOMBKcZqtqFzf+fmWQAZwByAHUAZAB6AGkAbgBzA...
Please, give me some examples how to encode domain username & password for that http header, i found only examples for BASIC authentication. But there are windows authentication & NTLM.
Put the domain credentials in the HttpClientHandler.Credentials property and the AuthorizationManager will do the Auth dance for you and fill in the Authorization header as required.
Related
I have a Web API application that we forward the HttpRequestMessage.Content to other methods that process the request. One of the set of values that is needed is the Headers that are sent as part of the request.
When I look at HttpRequestMessage.Headers.headerStore, I see all the headers sent to the request. But when I look at HttpRequestMessage.Content.Headers.headerStore, I only see a few of default headers.
Why doesn't HttpRequestMessage.Content.headerStore contain all the headers associated with the request?
Request headers and content headers have different purposes.
While request headers carry information about request itself and about client (caller), content headers describe "entity" or its metadata.
Have a look at sample http request:
POST /some/url HTTP/1.1
Host: someHost
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36
request Accept: application/json, text/plain, */*
headers Accept-Encoding: gzip,deflate
Connection: keep-alive
Referer: url
Content-Type: multipart/form-data; boundary=----------564564546545645
Content-Length: 462560
------------564564546545645
content Content-Disposition: form-data; name="file"; filename="1.png"
headers Content-Type: image/png
.PNG
......................;
------------564564546545645
I'm trying to log into the website of my school using c#. Using the software Fiddler, I've managed to capture the post request my browser makes and the post request I've recreated in c#. They seem to be completly identical, however the response I get is different. Shouldn't the server theoretically respond the same way if the post request is the same, at least with the same status code?
When I use my own client I get response code 200, but with my browser I get 303(which it should be).
Something I notice is that the WebForm content is much bigger in browser, but the values used in the client request are from a prior GET request. Sorry for the long post.
These are the requests captured by Fiddler:
Browser request:
POST https://www.lectio.dk/lectio/31/login.aspx HTTP/1.1
Host: www.lectio.dk
Connection: keep-alive
Content-Length: 881
Cache-Control: max-age=0
Origin: https://www.lectio.dk
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3
Referer: https://www.lectio.dk/lectio/31/login.aspx
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-AS;q=0.9,en-DK;q=0.8,en;q=0.7,da-DK;q=0.6,da;q=0.5,en-US;q=0.4
Cookie: LastLoginExamno=31;
ASP.NET_SessionId=ANTOMFZ7ZZWAYYW52OSZQYRXIBAIEGIPGILQHQ6TEJ2O5XEUTE3CAIBA; isloggedin3=N
time=0&__EVENTTARGET=m%24Content%24submitbtn2&__EVENTARGUMENT=&__SCROLLPOSITION=&__VIEWSTATEX=vQAAAGlpZQk1NDg4MjIyMjVpbAJrAIFsAmhpZGwCZwJpbAJrAWUDb2ZmbASBaWRsAoFpZGwCgWlkbAJoaWpkam4BZQcyMDE5LzIwbgFlBDIwMTl%2BAXFsAWhkZwNpZGwCZwVpZGwCaGlkbAJnB2lkbAaBaWwCawJlFE4mIzIzMDtydW0gR3ltbmFzaXVtZGcFaWRsAoFpZGwCgWlsAmsDZQI1MGRnB2lkbAKBaWRsAoFpamlsAmsEcGRkZGRkBQAAABNWYWxpZGF0ZVJlcXVlc3RNb2RlDGF1dG9jb21wbGV0ZQlpbm5lcmh0bWwJbWF4bGVuZ3RoB0NoZWNrZWQAXXvzIZezMAoPCqv5j%2FZuNIu6H1E%3D&__VIEWSTATEY_KEY=&__VIEWSTATE=&__EVENTVALIDATION=CY6WRLYHybmNGyj0%2FWgw9s%2BaewM2gnWAIUbvnFzgoYWgYPLkQnxHIBIpQPjEa3On7opgtRStMA%2FpLhG9PzzgXNTaWwTZIeSfKwS74n4yMULKRovRw2H%2Fwlg8HRUdJemRR%2FyFEzIkbToD8psr4CO9G3nzX706D25SYrmTc2WygXZ%2B1oYTAMe3FD7ocBdwh%2FrHRBAOaoTzCsCSlpMVce8GxcWKS3lryh8E8yVmy4AgrHpjgj3R0g1ziPKG96%2B1vVr%2B&m%24Content%24username2=username&m%24Content%24passwordHidden=password&LectioPostbackId=
C# client request:
POST https://www.lectio.dk/lectio/31/login.aspx HTTP/1.1
Cache-Control: max-age=0
Accept: text/html, application/xhtml+xml, application/xml; q=0.9, image/webp, image/apng, /; q=0.8, application/signed-exchange; v=b3
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB, en-AS; q=0.9, en-DK; q=0.8, en; q=0.7, da-DK; q=0.6, da; q=0.5, en-US; q=0.4
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
Referer: https://www.lectio.dk/lectio/31/login.aspx
Origin: https://www.lectio.dk
Upgrade-Insecure-Requests: 1
Connection: keep-alive
Cookie: LastLoginExamno=31;
ASP.NET_SessionId=DBYVNKXMKMO2F7XF7T22TM4RALBLKYPBQT42BGZX6H2UA5TZ2ZHCAIBA
Content-Type: application/x-www-form-urlencoded
Content-Length: 485
Host: www.lectio.dk
time=0&__EVENTTARGET=m%24Content%24submitbtn2&__EVENTARGUMENT=&__SCROLLPOSITION=&__VIEWSTATEX=FAAAAGlpZQotMTY2NzgzMzI1ZGQAAAAAALJLI4R47o%2FDmiaj2f9RNeeWl%2B5K&__VIEWSTATEY_KEY=&__VIEWSTATE=&__EVENTVALIDATION=%2FYOJVoNfWl%2F8olHfFefQyPMhqxIUan914QzoN6cFD0eGMukIp%2B%2FciKjpJU04AgXJhME7LttuUGcP8yOJ7xPSSP%2Bl8AnZk2DAdvMIFLFAAPD2Rf4K1DapTvDcnWnyz%2Bj1tesSoSUmLcmmh2E0ljSNR1Qr%2BUpIWQ91RtL1jS4GDh0%3D&m%24Content%24username2=povl0057&m%24Content%24passwordHidden=jdf59jcx&LectioPostbackId=
Shouldn't the server theoretically respond the same way if the post request is the same?
No
I have the following code that successfully connects to a third party API in C#:
using (var client = new WebClient())
{
client.Credentials = new NetworkCredential(login.Username, login.Password);
var xml = client.DownloadString(url);
Debug.Write(xml);
}
This works fine when connecting directly to the API. However, I'm trying to utilize Azure Traffic Manager to spread the load to multiple endpoints, and I'm getting 401 Unauthorized exceptions when doing this. It appears to work correctly using tools like Postman and configuring Basic Auth in the request.
I tried to convert the code to RestSharp but it appears to have the same symptoms.
Here are the request from Fiddler using a few different techniques:
C#/WebClient directly to API endpoint (Success)
GET <ApiUrl> HTTP/1.1
Host: <ApiHost>
Connection: Keep-Alive
401 Unauthorized
GET <ApiUrl> HTTP/1.1
Authorization: Basic <AuthToken>
Host: <ApiHost>
C#/WebClient to Azure Traffic Manager (401 Unauthorized)
GET <TrafficManagerApiUrl> HTTP/1.1
Host: <TrafficManagerApiHost>
401 Unauthorized
GET <ApiUrl> HTTP/1.1
Host: <ApiHost>
Postman to Azure Traffic Manager (Success)
GET <TrafficManagerApiUrl> HTTP/1.1
Host: <TrafficManagerApiHost>
Connection: keep-alive
Authorization: Basic <AuthToken>
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
Postman-Token: 13396800-33ab-8d7b-664f-68b99e8f4ac1
Accept: */*
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
302 Redirect
GET <ApiUrl> HTTP/1.1
Host: <ApiHost>
Connection: keep-alive
Authorization: Basic <AuthToken>
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
Postman-Token: 13396800-33ab-8d7b-664f-68b99e8f4ac1
Accept: */*
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Cookie: JSESSIONID=<jsessionid>
I wasn't properly handling the redirect of the Azure Traffic Manager.
The answer is detailed here:
https://stackoverflow.com/a/28671822/86191
I have a WPF (could be any winform I guess) app that tries to login to a standard MVC 5 website using a HttpClient.
Normally I can login successfully with a call to PostAsync() where I provide the UserName and Password params in a HttpContent!
However, when I add the [ValidateAntiForgeryToken] to my controller's Login (POST) action, the PostAsync() call fails with Internal Server Error.
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.
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?
EDIT 1:
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]
EDIT 2:
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
And finally this is the error:
[HttpAntiForgeryException (0x80004005): Validation of the provided anti-forgery token failed. The cookie "__RequestVerificationToken" and the form field "__RequestVerificationToken" were swapped.]
Thanks!
You d probably need to include aspnet session id cookie with your requests
EDIT:
OK ur right, it is not the session id, but you need two token to send back to your post action.
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.
It's because you're missing the anti-forgery token from HtmlHelper.AntiForgeryToken() in your POST from your application.
You'll need to load a page from your WPF application with HtmlHelper.AntiForgeryToken() on the view. Then take the value of the hidden input element with the name __RequestVerificationToken and attach it to your login POST request to the server.
When I look in fiddler RAW data, I see about 15 lines of data that goes to the server. I want to play that back exactly like fiddle does when I say replay request. I don't just want to add headers, but want the full request to go back. That is, I want to push something like what I have below (in c#).
Any suggestions?
POST https://www.smith.com/account/signin?returnurl=%2Faccount%2Fsignin%3Freturnurl%3D%252F HTTP/1.1
Host: www.smith.com
Connection: keep-alive
Content-Length: 81
Cache-Control: max-age=0
Origin: https://www.smith.com
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Referer: https://www.smith.com/account/signin
Accept-Encoding:
...