views:

1174

answers:

3

I have a web service that I can only hit if I'm logged into the website that the web service is on. I need to test the service remotely. So I've written some code to create a fake session that is logged into the site in another browser. Then I made the HTTP Web Request and I'm attempting to set a cookie that contains the ASP.NET session ID of that logged in user. But the web service doesn't detect that the web request is a logged in user or session. What do I need to give the web service to convince it this is a valid session?

// used on each read operation

byte[] buf = new byte[8192];

CookieContainer myContainer = new CookieContainer();

string sessionID = SessionID;

myContainer.Add(new Cookie("ASP.NET_SessionId", sessionID, "/", WebsiteUrl));

// prepare the web page we will be asking for
HttpWebRequest request = (HttpWebRequest)
    WebRequest.Create(CreateWebserviceUrl("doneScreenScore"));
request.ContentType = "text/xml; charset=utf-8";            
request.Method = "POST";
request.Accept = "text/xml";
request.Headers.Add("SOAPAction", "http://detectent.net/doneScreenScore");

request.CookieContainer = myContainer;

Stream s = request.GetRequestStream();

string soaprequest = "";
soaprequest += "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
soaprequest += "<soap12:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap12=\"http://www.w3.org/2003/05/soap-envelope\"&gt;";
soaprequest += "  <soap12:Body>";
soaprequest += "    <doneScreenScore xmlns=\"http://detectent.net/\"&gt;";
soaprequest += "      <input1>string</input1>";
soaprequest += "<input2>string</input2>";
soaprequest += "<input3>string</input3>";
soaprequest += "<input4>string</input4>";
soaprequest += "</doneScreenScore>";
soaprequest += "</soap12:Body>";
soaprequest += "</soap12:Envelope>";

s.Write(System.Text.Encoding.ASCII.GetBytes(soaprequest), 0, soaprequest.Length);

s.Close();

// execute the request
HttpWebResponse response = (HttpWebResponse)
    request.GetResponse();

// we will read data via the response stream
Stream resStream = response.GetResponseStream();
string responseFromWebServiceCall = ReadResponseStream(resStream);
+1  A: 

Without actually messing around with the thing myself I can't tell you exactly why it's not working. However I've done a bit of work writing applications which masquerade as a typical user for testing purposes and a tool I would recommend you familiarize yourself with is called WireShark. (Previously known as Ethereal)

WireShark is a packet sniffer. If you run it while browsing a website normally you will be able to see all the data being sent back and forth between your browser and the web server. Once you've found the information you need to make a request to this web service you should have no trouble constructing a proper WebRequest which behaves in the same manner.

You can download WireShark from the official site.

Spencer Ruport
+1  A: 

I think that you can do something with the credentials... I am doing this for a webservice...

rpt.Credentials = new System.Net.NetworkCredential(UserName, Password, Domain);

RSolberg
A: 

The NetworkCredentials work if the web site is using windows authentication.

I've had varying success impersonating a browser when doing this type of thing. Usually I have to make a valid request to their login page first. The response will contain a cookie with the SessionID. As long as I reuse the same CookieCollection for all the requests after that (ie. One global CookieCollection that is reused every request) it will work fine.

On the odd occasion, I still find that a website won't recognize my newly logged in session. In which case, I manually login with FireFox and use the WebDeveloper toolbar to view the cookies. I grab the cookie name/value and put them in the app settings, which is used by the program to populate the cookie collection.

Make sure you spoof a valid useragent too. I've had sites deny me because of that too.

Al W