Introduction
In this tip, we are going to look at how to invoke WebAPI that has basic or Windows authentication enabled.
Using the Code
In this tip, I will not talk about how to create WebAPI or how to host it. I will only be talking about how to access WebAPI from client using basic or Windows authentication.
Basic Authentication
Authentication information is sent as part of request header in case of basic authentication. Credentials are base64 encoded not encrypted. Because of this, basic authentication is secure only over HTTPS. It is relatively simple and supported by all major browsers.
This authentication is also vulnerable to CSRF (cross-site request forgery) attacks. Once the credentials are entered, the browser automatically sends them on subsequent requests to the same domain, for the duration of the session. Once logged in, there is no way to logout. If you want to logout, you have to end the session.
The below code shows how to invoke a WebAPI
with basic authentication.
var authenticationBytes = Encoding.ASCII.GetBytes("<username>:<password>");
using (HttpClient confClient = new HttpClient())
{
confClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(authenticationBytes));
confClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(Constants.MediaType));
HttpResponseMessage message = confClient.GetAsync("<service URI>").Result;
if (message.IsSuccessStatusCode)
{
var inter = message.Content.ReadAsStringAsync();
List<string> result = JsonConvert.DeserializeObject<List<string>>(inter.Result);
}
}
Windows Authentication
Windows authentication enables users to access the WebAPI
methods using their Windows credentials and is built into IIS. Credentials are sent in authorization header.
Intranet
applications are the best places to use this authentication. This is not a recommended way to authenticate internet applications and vulnerable to CSRF attacks.
Message handlers are used for setting Windows authentication details. So what is a message handler?
A message handler is a class that receives an HTTP request and returns an HTTP response. On the client side, the HttpClient
class uses a message handler to process requests. The default handler is HttpClientHandler
, which sends the request over the network and gets the response from the server.
Windows Authentication using HttpClientHandler
This class is the default message handler for HttpClient
. This class, and classes derived from it, enable us to configure a variety of options on an HTTP request like proxies and authentication. Even though this is the default message handler, in order to set authentication and other properties, an explicit object has to be created and passed on to HttpClient
. The code below shows how to use Windows authentication using this class. This class is under System.Net.Http
.
HttpClientHandler authtHandler = new HttpClientHandler()
{
Credentials = CredentialCache.DefaultNetworkCredentials
};
using (HttpClient confClient = new HttpClient(authHandler))
{
confClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(Constants.MediaType));
HttpResponseMessage message = getClient.GetAsync("<service URI>").Result;
if (message.IsSuccessStatusCode)
{
var inter = message.Content.ReadAsStringAsync();
List<string> result = JsonConvert.DeserializeObject<List<string>>(inter.Result);
}
}
Windows Authentication using WebRequestHandler
WebRequestHandler
derives from HttpClientHandler
, but it is not part of System.Net.Http
DLL. It is included in System.Net.Http.WebRequest
. It is needed to reference this DLL in order to work with WebRequestHandler
. This also requires an object to be created for setting the required properties and passed to HttpClient
. The below code shows how to set Windows authentication.
WebRequestHandler authtHandler = new WebRequestHandler()
{
Credentials = CredentialCache.DefaultNetworkCredentials
};
using (HttpClient confClient = new HttpClient(authHandler))
{
confClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(Constants.MediaType));
HttpResponseMessage message = getClient.GetAsync("<service URI>").Result;
if (message.IsSuccessStatusCode)
{
var inter = message.Content.ReadAsStringAsync();
List<string> result = JsonConvert.DeserializeObject<List<string>>(inter.Result);
}
}
History
- 05/31/2015 - First version
- 06/01/2015 - Update 1