I'm stuck on authentication to web site with webrequest on windows phone 8.
I have the following code:
PostMessage = string.Concat("job=LOGIN&password=&giftCode=&language=ua&login=%D0%9D%D0%BE%D0%BC%D0%B5%D1%80+%D0%BA%D0%B0%D1%80%D1%82%D0%BA%D0%B8&actn=&custId=&dateFrom=&dateTo=&showGift=&type=&card=&trnId=&catId=&subCatId=&awrId=&ordId=&qstId=&acqId=&", "crdNo=", cardNumber, "&PIN=", pin);
this.postDataBytes = Encoding.UTF8.GetBytes(PostMessage);
public void Load()
{
HttpWebRequest loginRequest = HttpWebRequest.CreateHttp(loginUrl);
loginRequest.ContentLength = this.postDataBytes.Length;
loginRequest.Method = "POST";
loginRequest.Accept = #"text/html, application/xhtml+xml, */*";
loginRequest.ContentType = "application/x-www-form-urlencoded";
loginRequest.Headers["Host"] = "*host*";
loginRequest.Headers["Referer"] = "*refer*";
loginRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko";
loginRequest.CookieContainer = new CookieContainer();
loginRequest.BeginGetRequestStream(OnBeginGetRequestStream, loginRequest);
}
private void OnBeginGetRequestStream(IAsyncResult result)
{
HttpWebRequest loginRequest = result.AsyncState as HttpWebRequest;
using (Stream stream = loginRequest.EndGetRequestStream(result))
{
stream.Write(this.postDataBytes, 0, this.postDataBytes.Length);
}
loginRequest.BeginGetResponse(OnAuthenticated, loginRequest);
}
private void OnAuthenticated(IAsyncResult result)
{
HttpWebRequest request = result.AsyncState as HttpWebRequest;
using (WebResponse response = request.EndGetResponse(result))
{
Stream responseStream = response.GetResponseStream();
using (StreamReader reader = new StreamReader(responseStream))
{
string page = reader.ReadToEnd();
}
}
}
It works sometimes... I mean this code do successfully authentication and return correct response. But sometimes it doesn't. Just ran this code few times and at some point I got correct response.
I tried to use fiddler but he doesn't want track requests from emulator.
Maybe someone know the reason of this strange behavior?
Did you look at this answer? I had the same problem, and the reason was cached response data.This answer is about win phone 7 but works for me on win phone 8.
Httpwebrequest caching in windows phone 7
Related
I have a download method for HTTP protocol. But it seems it doesnt work correctly, something is wrong. I tested it with some url sources and it was correct except the last one. The ContentLength property is wrong for the url. It is shown as 210 kb in runtime, but it is 8 MB in fact. I will show it by sharing my code. How to fix it?
Code:
void TestMethod(string fileUrl)
{
HttpWebRequest req = WebRequest.Create(fileUrl) as HttpWebRequest;
HttpWebResponse resp = req.GetResponse() as HttpWebResponse;
long contentSize = resp.ContentLength;
MessageBox.Show(contentSize.ToString());
}
private void TestButton_Click(object sender, EventArgs e)
{
string url1 = "http://www.calprog.com/Sounds/NealMorseDowney_audiosample.mp3";
string url2 = "http://www.stephaniequinn.com/Music/Canon.mp3";
TestMethod(url1); //This file size must be 8 MB, but it shows up as 210 kb. This is the problem
TestMethod(url2); //This file size is correct here, about 2.1 MB
}
I think you are not allowed to access this url this way (with HttpWebRequest).
if you try to get the response text :
HttpWebRequest req = WebRequest.Create(fileUrl) as HttpWebRequest;
HttpWebResponse resp = req.GetResponse() as HttpWebResponse;
using (var streamreader = new StreamReader(resp.GetResponseStream()))
{
var r = streamreader.ReadToEnd();
long contentSize = r.Length;
Console.WriteLine(contentSize.ToString());
}
You ll get this response :
<html><head><title>Request Rejected</title></head><body>The requested URL was rejected. If you think this is an error, please contact the webmaster. <br><br>Your support ID is: 2719994757208255263</body></html>
You must set the UserAgent to be able to get the full response. Like this :
req.UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:31.0) Gecko/20100101 Firefox/31.0";
By setting this value the server will think your program is a Firefox browser.
So these few lines of code should do the trick :
void TestMethod(string fileUrl)
{
HttpWebRequest req = WebRequest.Create(fileUrl) as HttpWebRequest;
req.UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:31.0) Gecko/20100101 Firefox/31.0";
HttpWebResponse resp = req.GetResponse() as HttpWebResponse;
long contentSize = resp.ContentLength;
Console.WriteLine(contentSize.ToString());
}
Have a good day !
I am trying to write some code to connect to an HTTPS site that uses Siteminder authentication.
I keep getting a 401. Any ideas?
I have read a few different things on here but none have really seemed all that helpful. I am also using Fiddler/Firefox Tamper to snoop what's going on.
Here is what I've got so far in regards to code:
try
{
Uri uri = new Uri("https://websiteaddresshere");
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri) as HttpWebRequest;
request.Accept = "text/html, application/xhtml+xml, */*";
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko";
// request.Connection = "Keep-Alive";
// request.Method = "Get";
// request.Accept = "text";
request.AllowAutoRedirect = true;
request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
Cookie emersoncookie = new Cookie("SMCHALLENGE", "YES");
emersoncookie.Domain = "mydomain";
emersoncookie.Path = "/";
// authentication
var cache = new CredentialCache();
cache.Add(uri, "False", new NetworkCredential("myusername", "mypassword"));
request.Credentials = cache;
// response.
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (Stream stream = response.GetResponseStream())
{
XmlTextReader reader = new XmlTextReader(stream);
MessageBox.Show(stream.ToString());
}
}
}
catch (WebException exception)
{
string responseText;
using (var reader = new StreamReader(exception.Response.GetResponseStream()))
{
responseText = reader.ReadToEnd();
MessageBox.Show(responseText.ToString());
}
}
After doing some more reading on the MSDN website I decided to go a different route.
I ended up making this a service since it will need to be a service at the end of the day and did the following:
CookieContainer emersoncookie = new CookieContainer();
HttpWebRequest request = (HttpWebRequest)
WebRequest.Create("https://websiteaddress");
request.Credentials = new NetworkCredential("username", "password");
request.CookieContainer = emersoncookie;
request.Method = "GET";
HttpWebResponse response = (HttpWebResponse)
request.GetResponse();
Stream resStream = response.GetResponseStream();
using (Stream output = File.OpenWrite(#"c:\\somefolder\\somefile.someextention"))
using (Stream input = resStream)
{
input.CopyTo(output);
}
To anyone that might be running into Siteminder authentication issues, this piece of code works pretty well.
I couldn't get Jasen's code to work. Maybe your SM setup is different from mine. But with SiteMinder it's generally a two step authentication process. The code block below works for me:
//Make initial request
RestClient client = new RestClient("http://theResourceDomain/myApp");
client.CookieContainer = new CookieContainer();
IRestResponse response = client.Get(new RestRequest("someProduct/orders"));
//Now add credentials.
client.Authenticator = new HttpBasicAuthenticator("username", "password");
//Get resource from the SiteMinder URI which will redirect to the correct API URI upon authentication.
response = client.Get(new RestRequest(response.ResponseUri));
Although this uses RestSharp, it can be easily replicated using HttpClient or even HttpWebRequest.
I'm trying to get simple gzip encoded html response from a website and it keeps getting time out, following is my code:
HttpWebRequest httpClient = (HttpWebRequest)WebRequest.Create(url);
httpClient.Method = "GET";
httpClient.Accept = "text/html, application/xhtml+xml, */*";
httpClient.Headers.Add("Accept-Encoding: gzip, deflate");
httpClient.Headers.Add("Accept-Language: en-US");
httpClient.Headers.Add("DNT: 1");
httpClient.ProtocolVersion = HttpVersion.Version10;
httpClient.KeepAlive = true;
httpClient.Timeout = System.Threading.Timeout.Infinite;
httpClient.CookieContainer = cookieJar;
String responseAsText;
using (HttpWebResponse response = (HttpWebResponse)httpClient.GetResponse())
{
System.IO.StreamReader sr;
if (response.ContentEncoding.Equals("gzip"))
{
sr = new StreamReader(new GZipStream(response.GetResponseStream(), CompressionMode.Decompress));
}
else
{
sr = new System.IO.StreamReader(response.GetResponseStream());
}
responseAsText = sr.ReadToEnd();
}
The url I'm trying to hit is "https client.schwab.com/Login/SignOn/CustomerCenterLogin.aspx"
This works perfectly fine in the Browser, using Fiddler I viewed the browser's Request header and since its Transfer-Encoding: chunked, I have used HttpVersion10
I have also tried setting httpClient.Timeout = System.Threading.Timeout.Infinite, but it never gets back with a response, however in browser the response gets in few seconds.
Please someone help me in achieving this.
probably you can try setting Agent property, so it doesn't recognize you as a bot.
I think Nero has answered your question ..
Try adding these Lines in your code..
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0";
I have a webbrowser control which loads a page.
I then hit a button to call this method:
public void get(Uri myUri)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(myUri);
CookieContainer cookieJar = new CookieContainer();
cookieJar.SetCookies(webBrowser1.Document.Url,webBrowser1.Document.Cookie.Replace(';', ','));
request.CookieContainer = cookieJar;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
int cookieCount = cookieJar.Count;
Stream receiveStream = response.GetResponseStream();
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
txt.Text = readStream.ReadToEnd();
txt2.Text = cookieCount.ToString();
}
As from the cookieCount int i can see that if i call the method before logging in on the page in the web browser control i would get 6 cookies, and after i log in i get 7.
However, even with the cookies the response i get is the same as if i wouldnt have been logged in.
So i am guessing that the cookies isnt being sent with the request?
Thanks!
You're recreating your CookieContainer every time you call this method, you need to use the same CookieContainer in all requests
you can use this code, to handle your requests:
static CookieContainer cookies = new CookieContainer();
static HttpWebRequest GetNewRequest(string targetUrl, CookieContainer SessionCookieContainer)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(targetUrl);
request.CookieContainer = SessionCookieContainer;
request.AllowAutoRedirect = false;
return request;
}
public static HttpWebResponse MakeRequest(HttpWebRequest request, CookieContainer SessionCookieContainer, Dictionary<string, string> parameters = null)
{
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.52 Safari/536.5Accept: */*";
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
request.CookieContainer = SessionCookieContainer;
request.AllowAutoRedirect = false;
if (parameters != null)
{
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
string postData = "";
foreach (KeyValuePair<String, String> parametro in parameters)
{
if (postData.Length == 0)
{
postData += String.Format("{0}={1}", parametro.Key, parametro.Value);
}
else
{
postData += String.Format("&{0}={1}", parametro.Key, parametro.Value);
}
}
byte[] postBuffer = UTF8Encoding.UTF8.GetBytes(postData);
using (Stream postStream = request.GetRequestStream())
{
postStream.Write(postBuffer, 0, postBuffer.Length);
}
}
else
{
request.Method = "GET";
}
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
SessionCookieContainer.Add(response.Cookies);
while (response.StatusCode == HttpStatusCode.Found)
{
response.Close();
request = GetNewRequest(response.Headers["Location"], SessionCookieContainer);
response = (HttpWebResponse)request.GetResponse();
SessionCookieContainer.Add(response.Cookies);
}
return response;
}
and to request a page,
HttpWebRequest request = GetNewRequest("http://www.elitepvpers.com/forum/login.php?do=login", cookies);
Dictionary<string,string> parameters = new Dictionary<string,string>{{"your params","as key value"};
HttpWebResponse response = MakeRequest(request, cookies, parameters);
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
if(!reader.EndOfStream)
{
Console.Write(reader.ReadToEnd());
}
}
When matching the session, your web server may be taking into account some other HTTP request headers, besides cookies. To name a few: User-Agent, Authorization, Accept-Language.
Because WebBrowser control and WebRequest do not share sessions, you'd need to replicate all headers from the WebBrowser session. This would be hard thing to do, as you'd need to intercept WebBrowser trafic, in a way similar to what Fiddler does.
A more feasible solution might be to stay on the same session with WebBrowser by using Windows UrlMon APIs like URLOpenStream, URLDownloadToFile etc., instead of WebRequest. That works, because WebBrowser uses UrlMon library behind the scene.
I've recently answered some related questions:
The notorious yet unaswered issue of downloading a file when windows security is required
Upload a file to a website programmatically?
After authorisation on www.vkontakte.ru through ie8 me spans on page: www.vkontakte.ru/MyPage. But I cannot receive www.vkontakte.ru/MyPage through a code
HttpWebRequest authRequest = (HttpWebRequest)WebRequest.Create(new Uri("http://vkontakte.ru/login.php", UriKind.Absolute));
authRequest.CookieContainer = new CookieContainer();
authRequest.AllowAutoRedirect = false;
string param = string.Format("email={0}&pass={1}&expire=1", HttpUtility.UrlEncode("---"), HttpUtility.UrlEncode("---"));
authRequest.Method = "POST";
authRequest.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)";
authRequest.ContentType = "application/x-www-form-urlencoded";
authRequest.ContentLength = param.Length;
authRequest.GetRequestStream().Write(Encoding.GetEncoding(1251).GetBytes(param), 0, param.Length);
HttpWebResponse authResponse = (HttpWebResponse)authRequest.GetResponse();
listBox1.Items.Add(authRequest.Address);
Returns http://vkontakte.ru/ instead of www.vkontakte.ru/MyPage =(
HttpContext.Current.Request.Url.AbsoluteUri - can help?
help me!
You forgot to close the request stream.
You should write the following:
using (Stream requestStream = authRequest.GetRequestStream())
using (StreamWriter writer = new StreamWriter(requestStream, Encoding.GetEncoding(1251))
writer.Write(param);
Also, you should run Fiddler check what the request and response look like.