C# WebRequest - HTTP: 403 Forbidden ('_xsrf' argument missing from POST) - c#

I'm stucked here at getting a WebResponse from HTTPWebRequest.
The WebRequest.GetResponse() Method throws a WebException
("500 Internal Server Error"). When i read the returned HTML it says:
HTTP 403: Forbidden ('_xsrf' argument missing from POST)
Anyone knows this Error or knows what Im doing wrong?
(Im trying to log in to a Website using POST)
EDIT:
My sourcecode:
private String GetLoginCookies(String pHTTPurl, String pUserIDwithFormID, String pPasswordWithFormID)
{
String loginPageUrl = pHTTPurl;
CookieContainer cookieContainer = new CookieContainer();
var Request = (HttpWebRequest)WebRequest.Create(loginPageUrl);
Request.CookieContainer = cookieContainer;
Request.Method = "GET";
WebResponse Response = Request.GetResponse();
HttpWebResponse HttpResponse = Response as HttpWebResponse;
CookieCollection cookies = null;
if (HttpResponse != null)
{
//Cookies die benötigt werden um den Loginvorgang abzuschließen
cookies = HttpResponse.Cookies;
}
string formParams = string.Format(pUserIDwithFormID + "&" + pPasswordWithFormID);
Request = (HttpWebRequest)WebRequest.Create(loginPageUrl);
Request.CookieContainer = cookieContainer;
Request.UserAgent = "I am not a Bot! Ok maybe..";
WebResponse resp = null;
Request.ContentType = "application/x-www-form-urlencoded";
Request.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(formParams);
Request.ContentLength = bytes.Length;
using (Stream os = Request.GetRequestStream())
{
os.Write(bytes, 0, bytes.Length);
}
try
{
resp = Request.GetResponse();
using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
{
String TestResponse = sr.ReadToEnd();
}
}
catch (WebException WE)
{
DebugConsole.AppendText("HTTP Error:" + WE.Message + Environment.NewLine);
String HTML = new StreamReader(WE.Response.GetResponseStream()).ReadToEnd();
DebugConsole.AppendText(HTML);
return null;
}
String cookieHeader = resp.Headers["Set-cookie"];
if (String.IsNullOrEmpty(cookieHeader))
return null;
else
return cookieHeader;
}

This is actually because the web method requires anti csrf (cross site request forgery, more info here: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)) validation parameter. What you can do, is to append the csrf value to the request header:
postHeaders.Add("X-CSRFToken", CSRF);
Maybe you can paste your source code here if you need any help with that, so we can look after it

OK! Solution found!
After getting the response of the Log-In site, search in the "Set-cookie" Header for _xsrf. This is the Token you have to put in the header of the next POST request.

Related

c# httpwebrequest for basic authentication

I've been trying to use a username, password and access key to authenticate on a server, so that I could use its API. I used to following code:
string encoded = Convert.ToBase64String(Encoding.Default.GetBytes("myusername:mypass"));
string api = "blahblahblahblabh";
string auth_string = "Basic " + encoded;
string _post_string = "username=myusername&password=mypass&grant_type=password";
HttpWebRequest request = WebRequest.Create(https_website) as HttpWebRequest;
request.Accept = "application/xml";
request.Method = "POST";
request.ContentType = "application/x-www-forms-urlencoded";
request.ContentLength = _post_string.Length;
CookieContainer cookies = new CookieContainer();
request.CookieContainer = cookies;
request.Headers["Authorization"] = auth_string;
request.Headers["api-key"] = api;
request.ServerCertificateValidationCallback += (sender1, certificate, chain, sslPolicyErrors) => { return true; };
StreamWriter writer = new StreamWriter(request.GetRequestStream());
writer.Write(_post_string);
writer.Close();
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
StreamReader reader = new StreamReader(response.GetResponseStream());
string xml_response = reader.ReadToEnd();
reader.Close();
So I sent a POST request with the username/password and access_key and tried to receive a response. I always get "The remote server returned an error: (404) Not Found". If I add more to the string of the 1st line, for example if instead of "myusername:mypass" I use "myusername:mypass:password" I get an error 401 (Unauthorized). I don't understand why this is happening...

Call Genderize.io API From C#

I'm trying to call http://genderize.io/ , but i'm getting an error from .NET saying:
{"You must provide a request body if you set ContentLength>0 or SendChunked==true. Do this by calling [Begin]GetRequestStream before [Begin]GetResponse."}
How would I call this web service "http://api.genderize.io/?name=peter" from C# and get a JSON string back?
HttpWebRequest request;
string postData = "name=peter"
URL = "http://api.genderize.io/?"
Uri uri = new Uri(URL + postData);
request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postData.Length;
request.AllowAutoRedirect = true;
UTF8Encoding enc = new UTF8Encoding();
string result = string.Empty;
HttpWebResponse Response;
try
{
using (Response = (HttpWebResponse)request.GetResponse())
{
using (Stream responseStream = Response.GetResponseStream())
{
using (StreamReader readStream = new StreamReader(responseStream, Encoding.UTF8))
{
return readStream.ReadToEnd();
}
}
}
}
catch (Exception ex)
{
Debug.WriteLine("Error: " + ex.Message);
throw ex;
}
You are making the call to the service using POST method, reading through the comments area in http://genderize.io/ the author states that only GET method requests are allowed.
Stroemgren: Yes, this is confirmed. Only HTTP GET request are allowed.
This answer probably would be better as a comment, but I don't have enough reputation :(

HttpWebRequest get 404 page only when using POST mode

First of all: I know this has been asked over 100 times, but most of these questions were eigher caused by timeout problems, by incorrect Url or by foregetting to close a stream (and belive me, I tried ALL the samples and none of them worked).
So, now to my question: in my Windows Phone app I'm using the HttpWebRequest to POST some data to a php web service. That service should then save the data in some directories, but to simplify it, at the moment, it only echos "hello".
But when I use the following code, I always get a 404 complete with an apache 404 html document. Therefor I think I can exclude the possibility of a timeout. It seems like the request reaches the server, but for some reason, a 404 is returned. But what really makes me be surprised is, if I use a get request, everything works fine. So here is my code:
HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.CreateHttp(server + "getfeaturedpicture.php?randomparameter="+ Environment.TickCount);
webRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0";
webRequest.Method = "POST";
webRequest.ContentType = "text/plain; charset=utf-8";
StreamWriter writer = new StreamWriter(await Task.Factory.FromAsync<Stream>(webRequest.BeginGetRequestStream, webRequest.EndGetRequestStream, null));
writer.Write(Encoding.UTF8.GetBytes("filter=" + Uri.EscapeDataString(filterML)));
writer.Close();
webRequest.BeginGetResponse(new AsyncCallback((res) =>
{
string strg = getResponseString(res);
Stator.mainPage.Dispatcher.BeginInvoke(() => { MessageBox.Show(strg); });
}), webRequest);
Although I don't think this is the reason, here's the source of getResponseString:
public static string getResponseString(IAsyncResult asyncResult)
{
HttpWebRequest webRequest = (HttpWebRequest)asyncResult.AsyncState;
HttpWebResponse webResponse;
try
{
webResponse = (HttpWebResponse)webRequest.EndGetResponse(asyncResult);
}
catch (WebException ex)
{
webResponse = ex.Response as HttpWebResponse;
}
MemoryStream tempStream = new MemoryStream();
webResponse.GetResponseStream().CopyTo(tempStream);
tempStream.Position = 0;
webResponse.Close();
return new StreamReader(tempStream).ReadToEnd();
}
This is tested code work fine in Post method with some body. May this gives you an idea.
public void testSend()
{
try
{
string url = "abc.com";
string str = "test";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "POST";
req.ContentType = "text/plain; charset=utf-8";
req.BeginGetRequestStream(SendRequest, req);
}
catch (WebException)
{
}
}
//Get Response and write body
private void SendRequest(IAsyncResult asyncResult)
{
string str = "test";
string Data = "data=" + str;
HttpWebRequest req= (HttpWebRequest)asyncResult.AsyncState;
byte[] postBytes = Encoding.UTF8.GetBytes(Data);
req.ContentType = "application/x-www-form-urlencoded";
req.ContentLength = postBytes.Length;
Stream requestStream = req.GetRequestStream();
requestStream.Write(postBytes, 0, postBytes.Length);
requestStream.Close();
request.BeginGetResponse(SendResponse, req);
}
//Get Response string
private void SendResponse(IAsyncResult asyncResult)
{
try
{
MemoryStream ms;
HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);
HttpWebResponse httpResponse = (HttpWebResponse)response;
string _responestring = string.Empty;
using (Stream data = response.GetResponseStream())
using (var reader = new StreamReader(data))
{
_responestring = reader.ReadToEnd();
}
}
catch (WebException)
{
}
}
I would suggest you to use RestSharp for your POST requests in windows phone. I am making an app for a startup and i faced lots of problems while using a similar code as yours. heres an example of a post request using RestSharp. You see, instead of using 3 functions it can be done in a more concise form. Also the response can be handled efficiently. You can get RestSharp from Nuget.
RestRequest request = new RestRequest("your url", Method.POST);
request.AddParameter("key", value);
RestClient restClient = new RestClient();
restClient.ExecuteAsync(request, (response) =>
{
if (response.StatusCode == HttpStatusCode.OK)
{
StoryBoard2.Begin();
string result = response.Content;
if (result.Equals("success"))
message.Text = "Review submitted successfully!";
else
message.Text = "Review could not be submitted.";
indicator.IsRunning = false;
}
else
{
StoryBoard2.Begin();
message.Text = "Review could not be submitted.";
}
});
It turned out the problem was on the server-side: it tried it on the server of a friend and it worked fine, there. I'll contact the support of the hoster and provide details as soon as I get a response.

Add Custom Headers using HttpWebRequest

I am not really sure what type of headers these highlighted values are, but how should I add them using HttpWebRequest?
Is the highlighted part considered body of the http request or header data? In other words, which way is correct?
Here is the code I am currently using:
HttpWebRequest request = (HttpWebRequest) WebRequest.Create("/securecontrol/reset/passwordreset");
request.Headers.Add("Authorization", "Basic asdadsasdas8586");
request.ContentType = "application/x-www-form-urlencoded";
request.Host = "www.xxxxxxxxxx.com";
request.Method = "POST";
request.Proxy = null;
request.Headers.Add("&command=requestnewpassword");
request.Headers.Add("&application=netconnect");
But should I use the following instead to build the Http Request above?
string reqString = "&command=requestnewpassword&application=netconnect";
byte[] requestData = Encoding.UTF8.GetBytes(reqString);
HttpWebRequest request = (HttpWebRequest) WebRequest.Create("/securecontrol/reset/passwordreset");
request.Headers.Add("Authorization", "Basic ashAHasd87asdHasdas");
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = requestData.Length;
request.Proxy = null;
request.Host = "www.xxxxxxxxxx.com";
request.Method = "POST";
using (Stream st = request.GetRequestStream())
st.Write(requestData, 0, requestData.Length);
A simple method of creating the service, adding headers and reading the JSON response,
private static void WebRequest()
{
const string WEBSERVICE_URL = "<<Web Service URL>>";
try
{
var webRequest = System.Net.WebRequest.Create(WEBSERVICE_URL);
if (webRequest != null)
{
webRequest.Method = "GET";
webRequest.Timeout = 20000;
webRequest.ContentType = "application/json";
webRequest.Headers.Add("Authorization", "Basic dcmGV25hZFzc3VudDM6cGzdCdvQ=");
using (System.IO.Stream s = webRequest.GetResponse().GetResponseStream())
{
using (System.IO.StreamReader sr = new System.IO.StreamReader(s))
{
var jsonResponse = sr.ReadToEnd();
Console.WriteLine(String.Format("Response: {0}", jsonResponse));
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
IMHO it is considered as malformed header data.
You actually want to send those name value pairs as the request content (this is the way POST works) and not as headers.
The second way is true.

Login to HTTPS Page via C#

I cant really seem to find this anywhere so I was wondering if you could help. I am trying to create a script which automatically logins to a HTTPS link via C#.
So essentially - I have a URL that contains a report I need to run daily but its behind a HTTPS login with username/password.
I am trying to create a script in C# which runs at X time, logins with username/password ? Any ideas?
Will love you long time!:)
Edit:---
OK now what if I want to save the *.txt file automatically to a database?
Here's some sample code that I wrote that logs into a website to send an SMS message:
private void sendMessage(SmsMessage message)
{
HttpWebRequest request;
HttpWebResponse response;
CookieContainer cookies;
string url = "http://www.xyzwebsite.com/";
try
{
request = (HttpWebRequest)WebRequest.Create(url);
request.AllowAutoRedirect = true;
request.CookieContainer = new CookieContainer();
response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
cookies = request.CookieContainer;
request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
String postData = "emailfrom="+credentials.Username+"&npa="+message.DestinationPhoneNumber.Substring(0,3)+"&exchange="+message.DestinationPhoneNumber.Substring(3,3)+"&number="+message.DestinationPhoneNumber.Substring(6)+"&body="+HttpUtility.UrlEncode(message.MessageText)+"&submitted=1&submit=Send";
byte[] data = System.Text.ASCIIEncoding.ASCII.GetBytes(postData);
request.ContentLength = data.Length;
Stream stream = request.GetRequestStream();
stream.Write(data, 0, data.Length);
request.CookieContainer = cookies;
stream.Close();
response = (HttpWebResponse)request.GetResponse();
response.Close();
}
else
{
Console.WriteLine("Client was unable to connect!");
}
}
catch (System.Exception e)
{
throw new SMSDeliveryException("Unable to deliver SMS message because " + e.Message, e);
}
}
WebClient and NetworkCredential shoudl solve that for you, examples:
https://web.archive.org/web/20211020134945/https://www.4guysfromrolla.com/articles/102605-1.aspx

Categories