I have created the following code, which as far as Im aware should work fine? It is not receiving any cookies at all, I have double checked with wire shark and the cookies are being returned... this is being developed on Windows Phone 7.
byte[] content = GetLoginRequestContent(username, password);
CookieContainer cookieContainer = new CookieContainer();
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(LoginUri);
httpWebRequest.ContentType = AuthContentType;
httpWebRequest.Method = "POST";
httpWebRequest.Headers["referer"] = LoginRequestReferer;
httpWebRequest.CookieContainer = cookieContainer;
httpWebRequest.Headers[HttpRequestHeader.ContentLength] = content.Length.ToString();
httpWebRequest.BeginGetRequestStream(async1 =>
{
using (Stream stream = httpWebRequest.EndGetRequestStream(async1))
stream.Write(content, 0, content.Length);
httpWebRequest.BeginGetResponse(async2 =>
{
HttpWebResponse rep = (HttpWebResponse)httpWebRequest.EndGetResponse(async2);
CookieCollection cookies = rep.Cookies;
using (Stream stream = rep.GetResponseStream())
using (StreamReader sr = new StreamReader(stream))
{
String contentX = sr.ReadToEnd();
//if blah blah
}
}, null);
}, null);
If the cookie is marked with HttpOnly (which is often the case with session cookies) you cannot access them it client side scripting for security reasons. It is sent to the client, the client resends it to the server (if it posses a cookie container) on subsequent requests, but you cannot read its value on the client.
Related
In C # application, when calling API interface, it often takes 15+ seconds to access. API is deployed in another network segment of intranet and needs to be accessed by proxy. Some one said that it was a DNS problem, try to setting the host, which has no effect.
Environment: Windows Server 2012 R2, IIS v8.5
Code Script:
private string PostHttp(string url, string authHeader, string requestBody)
{
var webRequest = System.Net.WebRequest.Create(url);
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);
byte[] data = System.Text.Encoding.UTF8.GetBytes(requestBody);
webRequest.Method = "POST";
webRequest.Headers.Add("Accept-Language", "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
webRequest.Headers.Add("Accept-Encoding", "gzip, deflate");
webRequest.Headers.Add("Authorization", authHeader);
webRequest.ContentLength = data.Length;
webRequest.ContentType = "application/x-www-form-urlencoded";
System.Net.WebProxy proxy = new System.Net.WebProxy("http://myHttpProxyAddress", false);
proxy.Credentials = new System.Net.NetworkCredential("HttpProxyUser", "HttpProxyPassword");
webRequest.Proxy = proxy;
var writer = webRequest.GetRequestStream();
writer.Write(data, 0, data.Length);
writer.Close();
using (WebResponse webResponse = webRequest.GetResponse())
{
System.IO.StreamReader reader = null;
if (webResponse.Headers["Content-Encoding"] == "gzip")
reader = new System.IO.StreamReader(new GZipStream(webResponse.GetResponseStream(), CompressionMode.Decompress), System.Text.Encoding.UTF8);
else
reader = new System.IO.StreamReader(webResponse.GetResponseStream(), System.Text.Encoding.UTF8);
var result = reader.ReadToEnd();
reader.Close();
return result;
}
}
it's very difficult to point out by just hearing someone said one of the possibility (e.g DNS error) , try to use some http utility (e.g Curl) to check and measure that.
you can wrap the request above with below this guide and measure the timing detail.
How do I measure request and response times at once using cURL?
I'm sending a request but the cookies are not being stored in my container for the response?
Example of code -
string uri = "https://www.localhost.com/"
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.ContentType = "application/x-www-form-urlencoded";
CookieContainer cookies = new CookieContainer();
request.CookieContainer = cookies;
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
using (Stream stream = request.GetRequestStream())
{
byte[] bytes = new UTF8Encoding().GetBytes(s);
stream.Write(bytes, 0, bytes.Length);
}
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (Stream stream2 = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(stream2, Encoding.UTF8))
{
str6 = reader.ReadToEnd();
}
}
}
as you can see I've implemented
CookieContainer cookies = new CookieContainer();
request.CookieContainer = cookies;
Which should store the cookies from the request within the container for further usage right within the response right? Like if the response needs the request cookies to load the page.
I suggest using HttpClient as it handles cookies for you and is just generally easier to work with. Also note that even though it’s disposable you generally should use the same HttpClient throughout your application. See: https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/
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..
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);
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.