views:

506

answers:

2

I need to login to a website and perform an action. The website is REST based so I can easily login by doing this (the login info is included as a querystring on the URL, so I dont't need to set the credentials):

CookieContainer cookieJar = new CookieContainer();

HttpWebRequest firstRequest = (HttpWebRequest) WebRequest.Create(loginUrl);
firstRequest.CookieContainer = cookieJar;
firstRequest.KeepAlive = true;
firstRequest.Method = "POST";
HttpWebResponse firstResponse = (HttpWebResponse)firstRequest.GetResponse();

That works and logs me in. I get a cookie back to maintain the session and it's stored in the cookieJar shown above. Then I do a second request such as this:

HttpWebRequest secondRequest = (HttpWebRequest) WebRequest.Create(actionUrl);
secondRequest.Method = "POST";
secondRequest.KeepAlive = true;
secondRequest.CookieContainer = cookieJar;
WebResponse secondResponse = secondRequest.GetResponse();

And I ensure I assign the cookies to the new request. But for some reason this doesn't appear to work. I get back an error telling me "my session has timed out or expired", and this is done one right after the other so its not a timing issue.

I've used Fiddler to examine the HTTP headers but I'm finding that difficult since this is HTTPS. (I know i can decrypt it but doesn't seem to work well.)

I can take my URL's for this rest service and paste them into firefox and it all works fine, so it must be something I'm doing wrong and not the other end of the connection.

I'm not very familiar with HTTPS. Do I need to do something else to maintain my session? I thought the cookie would be it, but perhaps there is something else I need to maintain across the two requests?

Here are the headers returned when I send in the first request (except I changed the cookie to protect the innocent!):

X-DB-Content-length=19
Keep-Alive=timeout=15, max=50
Connection=Keep-Alive
Transfer-Encoding=chunked
Content-Type=text/html; charset=WINDOWS-1252
Date=Mon, 16 Nov 2009 15:26:34 GMT
Set-Cookie:MyCookie stuff goes here
Server=Oracle-Application-Server-10g

Any help would be appreciated, I'm running out of ideas.

A: 

From MSDN:

When a user moves back and forth between secure and public areas, the ASP.NET-generated session cookie (or URL if you have enabled cookie-less session state) moves with them in plaintext, but the authentication cookie is never passed over unencrypted HTTP connections as long as the Secure cookie property is set.

So basically, the cookie can be passed over both HTTP and HTTPS if the 'Secure' property is set to 'false'.

see also http://stackoverflow.com/questions/567535/how-can-i-share-an-asp-net-session-between-http-and-https

Manu
Not sure I understand. I'm on the client, not the server side of this request. I need to maintain session across two or more calls to the server, but even though I'm bringing the cookie along it doesn't appear to recognize that I'm using the same session.
Kelly
He was a little confused assuming the site you're talking to was ASP.Net based, but regardless his suggestion was to set the cookie you get back after the first call's secure property to true and see if that works (I think)
John
I gave it a try. The cookies came back as secure=false. I set them to true for the second request, but still no luck.
Kelly
+1  A: 

I finally got it working after decrypting the HTTP traffic from my program.

The cookie I'm getting back doesn't list the Path variable. So .NET takes the current path and assigns that as the path on the cookie including the current page. ie: If it was at http://mysite/somepath/somepage.htm it would set the cookie path=/somepath/somepage.htm. This is a bug as it should be assigned to "/" which is what all web browsers do. (hope they fix this.)

After noticing this I grabbed the cookie and modified the path property and everything works fine now.

Anyone else with a problem like this check out Fiddler. .NET uses the windows certificate store so to decrypt http traffic from your program you will need to follow the instructions here: http://www.fiddler2.com/Fiddler/help/httpsdecryption.asp . You will also need to turn on decryption under the Options\HTTPS tab of Fiddler.

Kelly
Microsoft appears to have fixed this in .NET 4.
Kelly