I am using WebClient to try and access a web page. I have to login first and the site sets cookies.
I am using code from this question
The cookies are being set correctly, however when I try to access the second page I am just returned to the login page.
private WebClientEx client;
public string GetFile(string URL)
{
Login();
// Download desired page
return client.DownloadString(URL);
}
private void Login()
{
using (client)
{
var values = new NameValueCollection
{
{ "Login", "xxxx" },
{ "Password", "xxxx" },
};
// Authenticate
client.UploadValues("http://www.xxxxxx.com/backoffice/login.php");
}
return;
}
}
/// <summary>
/// A custom WebClient featuring a cookie container
/// </summary>
public class WebClientEx : WebClient
{
public CookieContainer CookieContainer { get; private set; }
public WebClientEx()
{
CookieContainer = new CookieContainer();
}
protected override WebRequest GetWebRequest(Uri address)
{
WebRequest request = base.GetWebRequest(address);
if (request.GetType() == typeof(HttpWebRequest))
((HttpWebRequest)request).CookieContainer = CookieContainer;
return request;
}
}
Related
I login with HTTPWebRequest and transfer the CookieContainer to the new class and want my WebClient to log in with this cookie and download a site as string. But I only get the source code of the login page, so it seems like the webclient won't login.
This is my current code:
BasicAuthentication login = new BasicAuthentication();
CookieContainer cookieJar = login.getCookie();
WebClientEx client = new WebClientEx();
client.Cookies = cookieJar;
And the WebClientEx Class
class WebClientEx : WebClient
{
private CookieContainer _cookies;
private string _ref;
public WebClientEx()
{
_cookies = new CookieContainer();
}
public CookieContainer Cookies
{
get { return _cookies; }
set { _cookies = value; }
}
protected override WebRequest GetWebRequest(System.Uri address)
{
var webReq = base.GetWebRequest(address);
if (webReq is HttpWebRequest)
{
var req = (HttpWebRequest)webReq;
req.CookieContainer = _cookies;
if (_ref != null)
{
req.Referer = _ref;
}
}
_ref = address.ToString();
return webReq;
}
protected override void Dispose(bool disposing)
{
_cookies = null;
base.Dispose(disposing);
}
}
I just get an Answer to my question.
Here's a example of my code:
WebClient client = new WebClient();
client.Headers.Add(HttpRequestHeader.Cookie, "cookievalue");
string download = client.DownloadString("url");
output.Text = download;
In the variable cookievalue I only enter the cookiename=cookievalue.
I get the name and the value from Postman, a useful google chrome tool.
I just have to make sure that i can redirect to any login proteccted page with postman and when this is true, then I can use cookiename and cookievalue to login my webclient and see all pages and download sites with downloadString.
I have the following code:
What do I put as the second argument for GetPage?
The second argument should be the previous cookie request of the same url.
for example I put google.com as the first argument to get the cookie when I make a get Request, but for the second how do I insert it?
static void Main()
{
GetPage("http://google.com/",cookieContainer??);
}
public class CookieAwareWebClient : WebClient
{
public CookieAwareWebClient(CookieContainer container)
{
CookieContainer = container;
}
public CookieAwareWebClient()
: this(new CookieContainer())
{ }
public CookieContainer CookieContainer { get; private set; }
protected override WebRequest GetWebRequest(Uri address)
{
var request = (HttpWebRequest)base.GetWebRequest(address);
request.CookieContainer = CookieContainer;
return request;
}
}
public HtmlAgilityPack.HtmlDocument GetPage(string url, CookieContainer CookieContainer)
{
Uri absoluteUri = new Uri("http://google.com/");
var cookies = CookieContainer.GetCookies(absoluteUri);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.CookieContainer = new CookieContainer();
foreach (Cookie cookie in cookies)
{
request.CookieContainer.Add(cookie);
}
request.Method = "GET";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
var stream = response.GetResponseStream();
using (var reader = new StreamReader(stream))
{
string html = reader.ReadToEnd();
var doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html);
return doc;
}
}
On the local network i have a similar page to this : http://demo.phpmyadmin.net/master (here use: username = "root", pass = blank)
In a Winforms app i need to pass the login/password and get this HTML: http://demo.phpmyadmin.net/master/server_status.php?db=&token=fda5205792a3caf29517c97c59ab1599
I'm looking for 3 days for a solution, but i can not get pass the login part.
This it the best i've got.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var client = new CookieAwareWebClient();
client.BaseAddress = #"http://demo.phpmyadmin.net/master";
var loginData = new NameValueCollection();
loginData.Add("input_username", "root");
//loginData.Add("password", "YourPassword");
client.UploadValues(#"http://demo.phpmyadmin.net/master", "POST", loginData);
string htmlSource = client.DownloadString("http://demo.phpmyadmin.net/master/server_status.php?db=&token=fda5205792a3caf29517c97c59ab1599");
richTextBox1.Text = htmlSource;
}
}
public class CookieAwareWebClient : WebClient
{
private CookieContainer cookie = new CookieContainer();
protected override WebRequest GetWebRequest(Uri address)
{
WebRequest request = base.GetWebRequest(address);
if (request is HttpWebRequest)
{
(request as HttpWebRequest).CookieContainer = cookie;
}
return request;
}
}
I have 2 sites, the first site is basic forms authentication system and some method, that needs to authenticate user. In the second I use modified WebClient (it can use cookies) and send request for authenticate and after request for secure operation. At first step all are OK, first server return AUTH cookie in response and remember it, and on the second it send request for secure operation with AUTH cookie, but at the first site, our request is not authorized! Request.isauthenticated = false.
Why is it? The AUTH cookie at this request are valid.
It is code for site №1 WebClient requests.
//Create an instance of your new CookieAware Web Client
var client = new CookieAwareWebClient();
//Authenticate (username and password can be either hard-coded or pulled from a settings area)
var values = new NameValueCollection { { "Name", "name" }, { "Password", "1234" } };
//Perform authentication - after this has been performed the cookie will be stored within the Web Client
client.UploadValues(new Uri("http://localhost:15536/Plugins/ProductListGetter/login"), "POST", values);
var _cookies = client.ResponseHeaders["Set-Cookie"];
client.UploadString(new Uri("http://localhost:15536/Plugins/ProductListGetter/ChangeNameForCurrentUser"), "POST", "Example Message");
client.UploadString(new Uri("http://localhost:15536/Plugins/ProductListGetter/ChangeNameForCurrentUser"), "POST", "Example Message");
client.Dispose();
And code for modified WebClient
public class CookieAwareWebClient : WebClient
{
//Properties to handle implementing a timeout
private int? _timeout = null;
public int? Timeout
{
get
{
return _timeout;
}
set
{
_timeout = value;
}
}
//A CookieContainer class to house the Cookie once it is contained within one of the Requests
public CookieContainer CookieContainer { get; private set; }
//Constructor
public CookieAwareWebClient()
{
CookieContainer = new CookieContainer();
}
//Method to handle setting the optional timeout (in milliseconds)
public void SetTimeout(int timeout)
{
_timeout = timeout;
}
//This handles using and storing the Cookie information as well as managing the Request timeout
protected override WebRequest GetWebRequest(Uri address)
{
//Handles the CookieContainer
var request = (HttpWebRequest)base.GetWebRequest(address);
request.CookieContainer = CookieContainer;
//Sets the Timeout if it exists
if (_timeout.HasValue)
{
request.Timeout = _timeout.Value;
}
return request;
}
Is there any way that I can actually use the cookies from a cookie container (taken from a WebRequest previously) and use them in a WebBrowser control? If so, how would I do this? This is for a Winforms application in C#.
You need to make use of InternetSetCookie. Here is a sample...
public partial class WebBrowserControl : Form
{
private String url;
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool InternetSetCookie(string lpszUrlName, string lbszCookieName, string lpszCookieData);
public WebBrowserControl(String path)
{
this.url = path;
InitializeComponent();
// set cookie
InternetSetCookie(url, "JSESSIONID", Globals.ThisDocument.sessionID);
// navigate
webBrowser.Navigate(url);
}
}
Here's an example oh how this could be achieved:
private class CookieAwareWebClient : WebClient
{
public CookieAwareWebClient()
{
CookieContainer = new CookieContainer();
}
public CookieContainer CookieContainer { get; private set; }
protected override WebRequest GetWebRequest(Uri address)
{
var request = base.GetWebRequest(address);
var httpRequest = request as HttpWebRequest;
if (httpRequest != null)
{
httpRequest.CookieContainer = CookieContainer;
}
return request;
}
}
private void Form1_Load(object sender, EventArgs e)
{
using (var client = new CookieAwareWebClient())
{
client.Proxy.Credentials = CredentialCache.DefaultNetworkCredentials;
client.DownloadData("http://www.google.com");
var cookies = client.CookieContainer.GetCookies(new Uri("http://www.google.com"));
var prefCookie = cookies["PREF"];
webBrowser1.Navigate("http://www.google.com", "", null, "Cookie: " + prefCookie.Value + Environment.NewLine);
}
}
Try to first use "client" CookedWebClient for the first navitation and get all the cookies from server. Then you can take the CookedContainer from CookedWebClient, or some other source like WebRequest, and use them in WebBrowser as shown below:
namespace ExampleWebBrowser
{
public partial class Form1 : Form
{
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool InternetSetCookie(string lpszUrlName, string lbszCookieName, string lpszCookieData);
CookedWebClient client = new CookedWebClient();
..
..
..
private void usingWebBrowserWithWebClientCookies(string url)
{
CookieCollection cookies = client.Cookies.GetCookies(url);
for (int i = 0; i < cookies.Count; i++)
{
Cookie c = cookies[i];
InternetSetCookie(url, c.Name, c.Value);
}
webBrowser1.Navigate(url);
}
}
public class CookedWebClient : WebClient
{
CookieContainer cookies = new CookieContainer();
public CookieContainer Cookies { get { return cookies; } }
protected override WebRequest GetWebRequest(Uri address)
{
WebRequest request = base.GetWebRequest(address);
if (request.GetType() == typeof(HttpWebRequest))
((HttpWebRequest)request).CookieContainer = cookies;
return request;
}
}
}