c# WebRequest cookies not working - c#

I am trying to get my c# console application to check if the credentials supplied are correct. But when I try it the web page gives a error:
<div id="login_error"> <strong>ERROR</strong>: Cookies are blocked or not supported by your browser. You must enable cookies to use WordPress.<br />
This is my code:
static bool SendRequest(string Username, string Password, string URL) {
string formUrl = URL;
string formParams = string.Format("log={0}&pwd={1}&wp-submit={2}&redirect_to={3}&testcookie={4}", Username, Password, "Log In", "http://localhost/wp-admin/", "1");
string cookieHeader;
WebRequest req = WebRequest.Create(formUrl);
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(formParams);
req.ContentLength = bytes.Length;
((HttpWebRequest)req).CookieContainer = new CookieContainer();
using (Stream os = req.GetRequestStream())
{
os.Write(bytes, 0, bytes.Length);
}
WebResponse resp = req.GetResponse();
cookieHeader = resp.Headers["Set-cookie"];
string pageSource;
using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
{
pageSource = sr.ReadToEnd();
}
Console.Write(pageSource);
return true;
}
I think the problem is that the cookies are not working but I have no clue how to fix this.
All help is appreciated!

You're not setting a CookieContainer to your HttpWebRequest, thus the default is set to null which means the client won't accept cookies.
CookieContainer from MSDN
The CookieContainer property provides an instance of the
CookieContainer class that contains the cookies associated with this
request.
CookieContainer is null by default. You must assign a
CookieContainer object to the property to have cookies returned in the
Cookies property of the HttpWebResponse returned by the GetResponse
method.
You must set a new CookieContainer before getting a response from the server.
req.ContentLength = bytes.Length;
((HttpWebRequest)req).CookieContainer = new CookieContainer();
// Rest of the code here..

Related

Get and Post using HttpWebRequest to log into website C# .Net

I created a c# console application to log into a website with Selenium and it works great. Now I want to add this feature to an existing .Net Core application.
So far I have the following:
string formUrl = "https://cap.mcmaster.ca/mcauth/login.jsp?app_id=1505&app_name=Avenue";
string formParams = string.Format("user_id={0}&pin={1}", "user", "pass"); //In my program I have the correct credentials
string cookieHeader;
var cookies = new CookieContainer();
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(formUrl);
req.CookieContainer = cookies;
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(formParams);
req.ContentLength = bytes.Length;
using (Stream os = req.GetRequestStream())
{
os.Write(bytes, 0, bytes.Length);
}
WebResponse resp = req.GetResponse();
cookieHeader = resp.Headers["Set-cookie"];
string pageSource;
string getUrl = "https://avenue.cllmcmaster.ca/d2l/home";
HttpWebRequest getRequest = (HttpWebRequest)WebRequest.Create(getUrl);
getRequest.CookieContainer = new CookieContainer();
getRequest.CookieContainer.Add(resp.cookies);
getRequest.Headers.Add("Cookie", cookieHeader);
getRequest.Headers.Add("Cookie", cookieHeader);
WebResponse getResponse = getRequest.GetResponse();
using (StreamReader sr = new StreamReader(getResponse.GetResponseStream()))
{
pageSource = sr.ReadToEnd();
}
For some reason, in the above code Cookies is underlined in "resp.Cookies" as an error. (CS1061 'WebResponse' does not contain a definition for 'Cookies' and no accessible extension method 'Cookies' accepting a first argument of type 'WebResponse' could be found)
I tried to folow the posts here: Login to website, via C# but I can't seem to get it to work.
The reason you are getting a compile time error is because the WebResponse class does not have a Cookies property.
From .NET Docs
The WebResponse class is the abstract base class from which
protocol-specific response classes are derived.
Instead, take a look at the HttpWebResponse class. This class provides a HTTP specific implementation of WebResponse.
You can cast the WebResponse to a HttpWebResponse:
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
HttpWebResponse.Cookies Property
Gets or sets the cookies that are associated with this response.
Documentation
HttpWebResponse.Cookies

How do I store a cookie after login

I'm trying to sign in to a website. It should be done by a POST request. But i need to store the cookie somehow.
My actual code:
public void botLogin(string userName, string passWord)
{
ASCIIEncoding encoding = new ASCIIEncoding();
string post_data = "username=" + userName + "&password=" + passWord;
byte[] data = encoding.GetBytes(post_data);
var requestUri = "http://registration.zwinky.com/registration/loginAjax.jhtml";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
var sharedCookies = new CookieContainer();
request.CookieContainer = sharedCookies;
Stream stream = request.GetRequestStream();
stream.Write(data, 0, data.Length);
stream.Close();
WebResponse response = request.GetResponse();
stream = response.GetResponseStream();
StreamReader sr = new StreamReader(stream);
MessageBox.Show(sr.ReadToEnd());
sr.Close();
stream.Close();
}
How would i store the cookie now to use it for other requests?
First of all, cast the created WebRequest to HttpWebRequest. This will give you access to more HTTP-specific properties and methods.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri);
Define a CookieContainer object at the application level and set that for each created request.
request.CookieContainer = sharedCookies;
I'm pretty sure, the HttpWebRequest object will store the cookies after the download so that the next request can use them. If that still doesn't work, examine the HttpWebResponse object for cookies (again, don't forget to cast the response object to that).

C# accessing HTTPS Files

I have figured out(by inspecting both the website its-self and the response form the website when using my C# application) that the website in question does not use the form's nor cookies to do the secure connections so I am wondering if anyone knows of a way to potentially use the SSL certificate or the website headers(which by all accounts I think do have a cookie in them), to allow the log-in and then download of a certain file.
Could I get code examples or links to ways to use the headers to log-in to a site is what I am asking, I have all the necessary credentials just not the extensive knowledge to use them.
Thanks a bunch.
public void downloadStuff()
{
string formUrl = "https://secure.website.co.nz/extension/Login.aspx";
string formParams = string.Format("ctl00_main_Login1_UserName={0}&ctl00_main_Login1_Password={1}", "*********", "************");
string cookieHeader;
WebRequest req = WebRequest.Create(formUrl);
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(formParams);
req.ContentLength = bytes.Length;
using (Stream os = req.GetRequestStream())
{
os.Write(bytes, 0, bytes.Length);
}
WebResponse resp = req.GetResponse();
cookieHeader = resp.Headers["Set-cookie"];
string pageSource;
string getUrl = "https://secure.website.co.nz/extension/Downloader.axd?x=stock-all";
WebRequest getRequest = WebRequest.Create(getUrl);
getRequest.Headers.Add("Cookie", cookieHeader);
WebResponse getResponse = getRequest.GetResponse();
using (StreamReader sr = new StreamReader(getResponse.GetResponseStream()))
{
WebClient exeed = new WebClient();
exeed.DownloadFileAsync(new Uri(#"https://secure.website.co.nz/extension/Downloader.axd?x=stock-all"), "test.txt");
pageSource = sr.ReadToEnd();
}
}
Note: This question was also put up because if what I have done is correct, I would not know how to use a cookie to download a file. Potentially example code of how to capture and use a cookie and or a header would be the best option.
Thanks, This was an edit!

Login to Https Website with WebRequest and WebResponse Not Working C#

I am working on a program that will log into a website and get certian data. However I am having trouble posting the login parameters and dealing with the cookies, as each time I get a page saying "You have logged out or Session has expired." So clearly I'm doing something wrong with posting the parameters or dealing with the cookies, but don't know which. I have been working on this for a while and just can't get my head around why this is not working correctly.
void Login2(string username, string password)
{
string pageSource;
string formUrl = "https://forUrl.com";
string formParams = string.Format("login={0}&sslProt={1}&pwd={2}&gru={3}", username, "", password, "115237091");
string cookieHeader;
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(formUrl);
req.AllowAutoRedirect = false;
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(formParams);
req.ContentLength = bytes.Length;
using (Stream os = req.GetRequestStream())
{
os.Write(bytes, 0, bytes.Length);
}
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
cookieHeader = resp.Headers["Set-cookie"];
string getUrl = "https://Urlbehindform.com";
HttpWebRequest getRequest = (HttpWebRequest)WebRequest.Create(getUrl);
getRequest.Method = "GET";
getRequest.AllowAutoRedirect = false;
getRequest.Headers.Add("Cookie", cookieHeader);
HttpWebResponse getResponse = (HttpWebResponse)getRequest.GetResponse();
using (StreamReader sr = new StreamReader(getResponse.GetResponseStream()))
{
pageSource = sr.ReadToEnd();
}
Response.Redirect(getUrl);
}
I am getting the cookie when I do the POST and sending it back when I do the GET, but for some reason this doesn't seem to work. At first I thought it was the parameters, but after looking at the issue further using Tamper Data with Firefox the login parameters seem to be working fine. Any help would be great, as I have been working on this for a while and can't wrap my head around it. Thanks!
UPDATE:
After trying out a few suggestions I still can't get this to work. However Upon looking deeper into Data Tamper, It appears that there is a POST with the login parameters, then a GET to a different page and then finally the GET to the page after the login page (The one I'm trying to get to). After some further debugging I actually discovered that my login POST is not working as I thought, As the response header location is showing "/cv/scripts/A028/eng/logErr.asp". Meaning the rest of my code could have been fine all a long, it was that the POST wasn't giving me a valid login. Any Sugguestions as to why I am always getting the login error page? As always thanks for the help.
UPDATE:
After playing around further with Tamper Data is appears that the reason I am unable to get a successful login is that in order have a successful POST of the parameters there needs to be a cookie already obtained. How do I go about doing this?
Use a single CookieContainer for both requests. Then you don't have to copy cookies manually.
I [BMW1] added in a CookieContainer called cookies, but it still not working, Im not sure if im using the CookieContainer the right way. Here is an updated version of my code.
And edited by me [Hans Kesting], see comments with [HK]
void Login2(string username, string password)
{
string pageSource;
string formUrl = "https://server/cv/scripts/A028/eng/logProc.asp?ntry=0&dbg=";
string formParams = string.Format("login={0}&sslProt={1}&pwd={2}&gru={3}", username, "", password, "115237091");
// [HK] create a container for the cookies, where they are added automatically
CookieContainer cookies = new CookieContainer();
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(formUrl);
req.CookieContainer = cookies;
req.AllowAutoRedirect = false;
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(formParams);
req.ContentLength = bytes.Length;
using (Stream os = req.GetRequestStream())
{
os.Write(bytes, 0, bytes.Length);
}
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
// [HK] no need to add cookies "by hand", that will happen automatically
//cookies.Add(resp.Cookies);
string getUrl = "https://server/cv/scripts/A028/eng/home.asp";
HttpWebRequest getRequest = (HttpWebRequest)WebRequest.Create(getUrl);
// [HK] use the same cookiecontainer as on the first request - correct
getRequest.CookieContainer = cookies;
getRequest.Method = "GET";
getRequest.AllowAutoRedirect = false;
HttpWebResponse getResponse = (HttpWebResponse)getRequest.GetResponse();
// [HK] no need to add cookies, they should be there already
//cookies.Add(getResponse.Cookies);
using (StreamReader sr = new StreamReader(getResponse.GetResponseStream()))
{
pageSource = sr.ReadToEnd();
}
// [HK] no need to add cookies, they should be there already
// cookies.Add(getResponse.Cookies);
Response.Redirect(getUrl);
}
You could use a Cookie aware web client,
public class CookieAwareWebClient : WebClient
{
public CookieContainer CookieContainer { get; set; }
public Uri Uri { get; set; }
public CookieAwareWebClient() : this (new CookieContainer())
{
}
public CookieAwareWebClient(CookieContainer cookies)
{
this.CookieContainer = cookies;
}
protected override WebRequest GetWebRequest(Uri address)
{
WebRequest request = base.GetWebRequest(address);
if (request is HttpWebRequest)
{
(request as HttpWebRequest).CookieContainer = this.CookieContainer;
}
HttpWebRequest httpRequest = (HttpWebRequest) request;
httpRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
return httpRequest;
}
protected override WebResponse GetWebResponse(WebRequest request)
{
WebResponse response = base.GetWebResponse(request);
String setCookieHeader = response.Headers[HttpResponseHeader.SetCookie];
if (setCookieHeader != null)
{
//do something if needed to parse out the cookie.
if (setCookieHeader != null)
{
Cookie cookie = new Cookie(); //create cookie
this.CookieContainer.Add(cookie);
}
}
return response;
}
}
Example usage:
var wc = new CookieAwareWebClient ();
wc.Headers["Content-type"] = "application/x-www-form-urlencoded";
string HtmlResult = wc.UploadString(URI, myParameters);

Why is my HttpWebRequest redirecting to Login page?

I have an HttpWebRequest to grab a session ID. I then get the cookie from the response, add it to a second request to get the page I need.
Using IIS/7.5, what are possible scenarios for this failing?
I am using Fiddler, and get a 302 status. I am getting the ASPNET SessionID.
CookieContainer myCookies = new CookieContainer();
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("https://www.secure.com/login.aspx");
req.Method = "POST";
req.Credentials = fileretrieve.Credentials;//Network credentials.
req.CookieContainer = myCookies;
req.AllowAutoRedirect = true;
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(req.Credentials.ToString());
req.ContentLength = bytes.Length;
System.IO.Stream os = req.GetRequestStream();
os.Write(bytes, 0, bytes.Length);
os.Close();
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
HttpWebRequest xmlreq = (HttpWebRequest)HttpWebRequest.Create("https://www.secure.com/file");
xmlreq.Method = "GET";
xmlreq.KeepAlive = true;
xmlreq.AllowAutoRedirect = true;
xmlreq.CookieContainer = req.CookieContainer;
HttpWebResponse xmlresp = (HttpWebResponse)xmlreq.GetResponse();
string webpage;
System.IO.StreamReader sr = new System.IO.StreamReader(xmlresp.GetResponseStream());
webpage = sr.ReadToEnd();
I think it is failing because you are trying to use .Credentials property to authenticate in FormsAuthentication-based application. Credentials property would work for Basic or NTLM authentication, but not for Forms authentication, in that case you just need to POST expected fields to Login.aspx page in order to get Auth cookie back.

Categories