PreAuthenticate Property of WebRequest - Problem
There is a common misunderstanding about how the PreAuthenticate property of .NET's System.Net.WebRequest class works, for example when using Basic Authentication. In this post I'll explain how it actually works and in the next post I'll describe how to use WebRequest to get the behaviour that is often erroneously expected when PreAuthenticate is used. Say this code is used to retrieve two HTTP resources:
using System;
using System.IO;
using System.Net;
class Program
{
static string Get(string uri)
{
WebRequest req = WebRequest.Create(uri);
req.Credentials = new NetworkCredential("user", "password",
"cookcomputing.com");
req.PreAuthenticate = false; // default for WebRequest
Stream stm = req.GetResponse().GetResponseStream();
string ret = new StreamReader(stm).ReadToEnd();
return ret;
}
static void Main(string[] args)
{
Console.WriteLine(Get("http://localhost:81/foo/foo.html"));
Console.WriteLine(Get("http://localhost:81/foo/bar.html"));
}
}
There will be four round-trips between the client and server (for the time being assume the server does not have HTTP Keep-Alive enabled):
- Client: GET /foo/foo.html HTTP/1.1
-
Server: HTTP/1.1 401 Access Denied
WWW-Authenticate: Basic realm=" cookcomputing.com" -
Client: GET /foo/foo.html HTTP/1.1
Authorization: Basic c3RvY2tsZXkuYXZheWEuY29tXGNoY29vazpBcmVuaWcxNjAh - Server: HTTP/1.1 200 OK
- Client: GET /foo/bar.html HTTP/1.1
-
Server: HTTP/1.1 401 Access Denied
WWW-Authenticate: Basic realm="cookcomputing.com" -
Client: GET /foo/bar.html HTTP/1.1
Authorization: Basic c3RvY2tsZXkuYXZheWEuY29tXGNoY29vazpBcmVuaWcxNjAh - Server: HTTP/1.1 200 OK
req.PreAuthenticate = true;
In fact this is what actually happens:
- Client: GET /foo/foo.html HTTP/1.1
-
Server: HTTP/1.1 401 Access Denied
WWW-Authenticate: Basic realm=" cookcomputing.com" -
Client: GET /foo/foo.html HTTP/1.1
Authorization: Basic c3RvY2tsZXkuYXZheWEuY29tXGNoY29vazpBcmVuaWcxNjAh - Server: HTTP/1.1 200 OK
- Client: GET /foo/bar.html HTTP/1.1
- Server: HTTP/1.1 200 OK
Note that if the server has enabled HTTP KeepAlive and the default value of true for HttpWebRequest.KeepAlive has not been changed, then assuming the connection remains open for the second request, the successful authorization for the first request will still apply and the use of PreAuthenticate is not required.