So I managed to login to my site from C# winforms(with a cookie...), so that forbidden pages are accessible once I get the cookie but the problem arises when I try to post new data once I log in succesfully...then I'm getting "403 forbidden".
In other words:
- I send POST from C# using login/password and if succesful I get a cookie and...store it somewhere (I think);
- Once the cookie is stored, I can use the usual DownloadString method to visit pages that otherwise require logging in;
- However despite saving the cookie I cannot send POST again because the server thinks I am not logged in and I get "403 foribdden"?
Here is the class I am using to help me login, again this works for logging in but not for posting(e.q. editing details...) once I am logged in:
///helper, WebClient derrived class below
public class CookieAwareWebClient : WebClient
{
public CookieContainer cookie = new CookieContainer();
//Properties to handle a timeout
private int? _timeout = null;
public int? Timeout
{
get
{
return _timeout;
}
set
{
_timeout = value;
}
}
public void SetTimeout(int timeout)
{
_timeout = timeout;
}
//Properties to handle SSL
private bool? _ssl = null;
public bool? Ssl
{
get
{
return _ssl;
}
set
{
_ssl = value;
}
}
public void SetSsl(bool ssl)
{
_ssl = ssl;
}
protected override WebRequest GetWebRequest(Uri address)
{
WebRequest request = base.GetWebRequest(address);
if (request is HttpWebRequest)
{
(request as HttpWebRequest).CookieContainer = cookie;
if (_timeout.HasValue)
{
request.Timeout = _timeout.Value;
}
if (_ssl.Value==true)
{
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
}
}
return request;
}
}
//main implementation and usage of the above class below:
public void something()
{
var client = CookieAwareWebClient();
client.Ssl = true;
ServicePointManager.ServerCertificateValidationCallback =
delegate(object
s, X509Certificate certificate, X509Chain chain, SslPolicyErrors
sslPolicyErrors) { return true; };
client.Timeout = 7000;
client.BaseAddress = "http://localhost:8080/";
var loginData = new NameValueCollection();
loginData.Add("username", "admin");
loginData.Add("password", "admin");
try
{
client.UploadValues("login.php", "POST",loginData);
}
catch (Exception r)
{
MessageBox.Show(r.ToString());
}
try
{
string loggedin=client.DownloadString("http://localhost:8080/" + "/admin");
Match checking_if_weare_loggedin = Regex.Match(loggedin, @"Jake");
string checking = checking_if_weare_loggedin.ToString();
if (checking.Length > 3)
{
MessageBox.Show("Good, you're logged in, I can see 'Jake' in the html of the page!");
}
else
{
MessageBox.Show("Something is not right...this shouldn't
happen as try-catch cant even catch it!");
}
}
The above part works, but this below is NOT working:
try
{
client.UploadValues("edit.php", "POST", loginData2);
}
catch (Exception r)
{
MessageBox.Show("lol error" + r.ToString());
}
///
To summarize, if I use client.DownloadString, the DownloadString method is obviously keeping track of my cookies since if I use the correct password/username I am able to visit the "admin" page and regular expression can browse it and read the "welcome" message/html source.
However unlke the downloadstring method, the uploadstring starts from scratch?
So, how to override Webclient so that the cookie is stored no matter what method I'm using?
Thanks alot! (I hope the code above is useful at least for people who want to login as it has SSL/Timeout values implemented, it's pretty good for logging in and reading html but again, it's not working if you want to keep posting once you log in successfully).