HttpWebRequest and Authentication - Part 1

Authentication over HTTP is a way for a client to prove its identity to the server so that it can gain access to a resource. In this series I will discuss the various types of authentication to servers and to proxy servers. I assume you have a basic understanding of HTTP including the use of headers and status codes. Note that all Url’s listed are examples and may or may not exist.

HTTP Authentication to a web server

When a client requests a resource to which the server does not allow anonymous access, the server will send a 401 error response to the client. Included in that response will be information that the client can use to determine which types of authentication the server supports. Here is an example request/response where the server responds with a 401 (some data has been left out so we can focus on the important information).

 
-------  Request -------
GET /protectedResource/file.htm HTTP/1.1
Host: www.contoso.com



-------  Response -------
HTTP/1.1 401 Unauthorized
WWW-Authenticate: NTLM,Negotiate,Kerberos,Digest qop="auth",algorithm=MD5-sess,
 nonce="c48850fd6e86c4013da6abceeb068c10ad9a668010af099834b51942bbb13f9ab5f6e65f2d89a802",
 opaque="39e6d50b360984701e23589a4a684347",charset=utf-8,realm="Digest",Basic realm="www.contoso.com"

Note the response contains the header “www-authenticate” which includes the types of authentication the server supports. It lists NTLM, Negotiate, Kerberos, Digest (plus some input parameters for Digest – explained in a later post) and Basic as supported authentication schemes.

The client then chooses from this list an authentication type that it also supports (if any). HttpWebRequest will choose the most secure protocol supported by both the client and server. The server and client then exchange information (possibly multiple times depending on the authentication type) so that the client can prove its identity to the server (which can also prove the identity of the server also). The client then resubmits the same request it issued earlier, but adds the “Authorization” header that contains the keyword “Basic” so that the server knows which type of authentication the client chose followed by a blob of data that the server should use to identify the client. In this example, the client chooses Basic authentication for simplicity’s sake (even though in the real world HttpWebRequest would not have chosen this authentication type above the others).

 
-------  Request -------
GET /protectedResource/file.htm HTTP/1.1
Host: www.contoso.com
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

The server then either sends back another 401 letting the client know that it failed to authenticate or it sends back 200 response status code so that the client knows that it passed the test.

 
-------  Response -------
HTTP/1.1 200 OK
Content-Length: 512

HTTP Authentication to a proxy server

Authentication to a proxy server is similar with a few modifications. The client still sends the same request to the proxy but instead of getting a 401 response status code it will get a 407 status code indicating that the proxy (as opposed to the end server) wants the client to authenticate. The proxy will also send back a “Proxy-Authenticate” header in place of the “www-authenticate” header. When the client goes to send the blob back to the proxy it will use the “proxy-authorization” header instead of the “authorization” header.