I want to log in to my Drupal site via a C# application and have been using OAuth and Services with no success. Is there a way to log in with a session from C#? I need to do this to access my private files on my Drupal site.
I tried to use the code below from a user here on stackoverflow with now success. I get 403 when using the code.
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;
}
}
var client = new CookieAwareWebClient();
client.BaseAddress = #"https://www.mysite.com/";
var loginData = new NameValueCollection();
loginData.Add("login", user);
loginData.Add("password", password);
client.UploadValues("login.php", "POST", loginData); // ERROR HERE
//Now you are logged in and can request pages
string htmlSource = client.DownloadString("index.php");
There is no login.php in drupal. I think you need to check these examples: (RPC / Services 3)
https://drupal.org/node/308629
http://www.technogumbo.com/2012/05/Drupal-7-Services-3-REST-Server-C-Sharp-Example/
Related
I am creating an application for data retrieval from the web page. The page is password protected and when the user logs in the cookie is created.
In order to retrieve the data the application first has to log in: make web request with username and password and store the cookie. Then when the cookie is stored it has to be added into the headers of all requests.
Here is the method which makes requests and retrieves the content:
public void getAsyncDailyPDPContextActivationDeactivation()
{
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(dailyPDPContextActivationDeactivation);
IAsyncResult asyncResult = httpWebRequest.BeginGetResponse(null, null);
asyncResult.AsyncWaitHandle.WaitOne();
using (HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.EndGetResponse(asyncResult))
using (StreamReader responseStreamReader = new StreamReader(httpWebResponse.GetResponseStream()))
{
string responseText = responseStreamReader.ReadToEnd();
}
}
Does anyone know how to modify this method in order to add a cookie into the header?
I would be also thankful if anyone suggested a way to store cookie from the response (when the application makes a request http:xxx.xxx.xxx/login?username=xxx&password=xxx the cookie is created and has to be stored for future requests).
CookieContainer cookieContainer = new CookieContainer();
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(...);
httpWebRequest.CookieContainer = cookieContainer;
Then you reuse this CookieContainer in subsequent requests:
HttpWebRequest httpWebRequest2 = (HttpWebRequest)WebRequest.Create(...);
httpWebRequest2.CookieContainer = cookieContainer;
Use the CookieContainer or you could use a CookieAwareWebClient
My Code:
class MyWebClient : WebClient
{
private CookieContainer _cookieContainer = new CookieContainer();
protected override WebRequest GetWebRequest(Uri address)
{
WebRequest request = base.GetWebRequest(address);
if (request is HttpWebRequest)
{
(request as HttpWebRequest).CookieContainer = _cookieContainer;
}
return request;
}
}
using (var client = new MyWebClient())
{
var data = new NameValueCollection
{
{ "username", "myUser" },
{ "password", "myPw" }
};
client.UploadValues("http://www..tv/takelogin.php", data);
}
MNM3.4:
Response:
Building my app i use 3 sites.. with 2 of them everything works fine but with this no.
Passing a CookieContainer usually does the trick but you're already sending it. Can you confirm the field names?
Also, for some websites, you'll need to post back the hidden fields. I usually perform a GET to the login page and, using an HTML parser (like HtmlAgilityPack), I locate the appropriate form and POST the login request with all INPUT/SELECT fields I find.
I think the best advice here is to use a debugging proxy like Fiddler and try to perform the login from the browser and inspect the generated traffic.
I Found the problem...
client.UploadValues("http://www..tv/takelogin.php", data);
changed to:
client.UploadValues("http://.tv/takelogin.php", data);
That means:
http://www.MY_SITE.tv
dont work, but
http://MY_SITE.tv
works fine.
My question is how can I do POST request, next get cookie from that request and set it to the next request for example GET type in C#? Please for example code.
I had tried a lot of times, for example by CookieAwareWebClient method but it not working:
public class CookieAwareWebClient : WebClient
{
public CookieContainer CookieContainer { get; set; }
public CookieAwareWebClient()
: base()
{
CookieContainer = new CookieContainer();
}
protected override WebRequest GetWebRequest(Uri address)
{
WebRequest request = base.GetWebRequest(address);
HttpWebRequest webRequest = request as HttpWebRequest;
if (webRequest != null)
{
webRequest.CookieContainer = CookieContainer;
}
return request;
}
}
What I need? I need to login by POST requests and next do for example 10-20 request POST/GET by the authenticate cookie from first request (login)
I'm doing it by this:
//Create an instance of your new CookieAware Web Client
using (var client = new CookieAwareWebClient())
{
//Authenticate (username and password can be either hard-coded or pulled from a settings area)
var values = new NameValueCollection{{ "UserName", username },{ "Password", password }};
client.UploadValues(new Uri("http://www.yourdomain.com/Account/LogOn/"), "POST", values);
client.UploadString(new Uri("http://www.yourdomain.com/Secure/YourSecureMethod"),
"POST", "Example Message");
}
But I cant set this cookie to my next requests (next reauest creating thier own NEW non-authenticated cookies)
I'm using a web client that is cookie aware
public class CookieAwareWebClient : WebClient
{
public CookieContainer m_container = new CookieContainer();
protected override WebRequest GetWebRequest(Uri address)
{
WebRequest request = base.GetWebRequest(address);
if (request is HttpWebRequest)
{
(request as HttpWebRequest).CookieContainer = m_container;
}
return request;
}
public CookieCollection Cookies(Uri domain)
{
return m_container.GetCookies(domain);
}
}
And making a few request to a web site that drops a set of cookies like this
webClient.Cookies(new Uri("http://<domain>.com")).Cast<Cookie>().ToArray()
{System.Net.Cookie[7]}
[0]: {UsrLocale=en_CA}
[1]: {Country=CA}
[2]: {$Version=1; ca_ord="UJMupexgTADsaH1yNi9eyA=="; $Path=/; $Domain=.<domain>.com}
[3]: {isLoggedin=false}
[4]: {cartCount=1}
[5]: {userPrefLanguage=en_CA}
The next request doesn't work as expected, and when I look in fiddler I see that cookie[2] hasn't been added to the headers. This one is pretty important by the looks of things. Does anyone know why it wouldn't be added to the request? All the others get popped in fine, and the domain I'm making a request to is a subdomain of the one listed in the cookie i.e. subDomain..com
var domain = new Uri("http://domain.com");
var webClient = new CookieAwareWebClient();
webClient.OpenRead("http://sub.domain.com");
webClient.RefreshCookies(domain);
webClient.UploadValues("http://sub.domain.com/browse/submit.jsp", new NameValueCollection
{
{"productId","prod610181"},
{"skuId","3431733"},
{"quantity","1"},
{"page","MAIN"}
});
webClient.RefreshCookies(domain);
webClient.OpenRead("http://sub.domain.com/shopping/bag.jsp");
webClient.RefreshCookies(domain);
var order = webClient.Cookies(new Uri("http://domain.com")).Cast<Cookie>().ToArray();
I am trying to access a webpage on a same domain / same asp.net application, that is password protected. Credentials are the same both for webpage firing this call and webpage being accessed.
Here is the code, and I don't know why I always end up with a login form html code?
using (WebClient client = new WebClient())
{
client.QueryString.Add("ID", "1040"); //add parameters
//client.Credentials = CredentialCache.DefaultCredentials;
//I tried to add credentials like this
client.Credentials = new NetworkCredential("username", "password");
string htmlCode = client.DownloadString("http://domain.loc/testpage.aspx");
}
I suspect that the web page that you are trying to access uses Forms Authentication. This means that you will have to provide a valid authentication cookie if you want to be able to access protected resources. And in order to obtain a valid authentication cookie you will have to first authenticate yourself by sending a POST request to the LogOn page which emits the cookie. Once you retrieve the cookie you will be able to send it along on subsequent requests on protected resources. You should also note that out of the box WebClient doesn't support cookies. For this reason you could write a custom cookie aware web client:
public class CookieAwareWebClient : WebClient
{
public CookieAwareWebClient()
{
CookieContainer = 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;
}
}
Now you could use this client to fire off the 2 requests:
using (var client = new CookieAwareWebClient())
{
var values = new NameValueCollection
{
{ "username", "john" },
{ "password", "secret" },
};
client.UploadValues("http://domain.loc/logon.aspx", values);
// If the previous call succeeded we now have a valid authentication cookie
// so we could download the protected page
string result = client.DownloadString("http://domain.loc/testpage.aspx");
}
Obviously due to the ViewState crapiness of ASP.NET you might need to send a couple of other parameters along your logon request. Here's what you could do: authenticate in a web browser and look with FireBug the exact parameters and headers that need to be sent.