Accessing cookies returned in error responses with httpwebrequest (.net CF)

A

Alex White

Hi,

I'm currently developing an application on the ppc using the .NET
compact framework, using HttpWebRequest and HttpWebResponse in
asynchronous mode.

I'm currently trying to authenticate (basic authentication) with a
site protected by third party security software, and the initial
request to the site returns a 401 (Access Denied). I can implement
authentication using the NetworkCredential class, assigning this to
the Credentials property.

The problem is that the site uses cookies to track the user attempting
access, and the 401 response includes some cookies which need to be
passed back with the authentication details. Otherwise I cannot gain
access.

We all know that the CF does not support cookies, and I've overcome
this problem in a different area by retrieving the important cookies &
reinserting them manually (using the Headers property of the response
and request), but when a 401 is returned from the site, I have no
HttpWebResponse object to poach them from. (The call to EndGetResponse
is supposed to return the HttpWebResponse object, but throws an
exception in the case of a 401).

I have a test application that I can run in the conventional
framework, and I can replicate the problem by disabling the cookies.
The authentication works as soon as I set the cookie container. So I
know that the cookies are definitely the problem.

Does anyone know how to access the headers returned in a server error
response?

Cheers,
Alex.
 
F

Feroze [msft]

If I understand you correctly, the handshake goes like this:

Client: GET to server
Server: 401, with Set-Cookie header & WWW-Authenticate header.
Client: GET to server, with Cookie, and Authorization header containing
credentials.

If so, you can try the following:

Do not set credential on the request. Issue a request to the server. You
will get back an exception. you can get headers from the response object by
doing the following:

HttpWebResponse resp = null;
string cookie = null;
try {
resp = req.GetResponse() as HttpWebResponse;
} catch(WebException e) {
if(e.Status == WebExceptionStatus.ProtocolError) {
resp = e.Response as HttpWebResponse;
if((int)resp.Status == 401) {
cookie = resp.Headers["Set-Cookie"];
}
// optionally, get the response stream, read it & close it.
resp.Close();
}
}

Once you get the cookie, you can set it on the next request, along with the
credentials.

// next request.
req = (HttpWebRequest)WebRequest.Create("...");
req.Headers["Cookie"] = cookie;
req.Credentials = new NetworkCredential(...);
try {
resp = req.GetResponse() as HttpWebRequest;
} catch(...) {
...
}


The key thing to note here is that the first request should not have the
credentials set on them. Otherwise the CF will try to do the auth handshake,
and since it doesnt support cookies, it will not succeed.

--
feroze

-----------------
This posting is provided as-is. It offers no warranties and assigns no
rights.

See http://weblogs.asp.net/feroze_daud for System.Net related posts.
----------------
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top