OAuth authentication client with .NET

One of the most authentication protocol used today in the web application is OAuth, as you know the token-based authentication protocol, where a client send the credential for the authentication, and if all goes well it receives a bearer token that the client will use for the further requests to the server.

If I want to implement a C# client that send requests to a OAuth based application, the .NET framework give me some different options, that I want to describe in this post.

WebRequest

This is the first class implemented in the framework for this purpose and the most syntactically verbose, it was introduced in the .NET Framework 2.0.

If we want to send an authentication request to the application and get the access token, we need to write a code like this:

var request = WebRequest.CreateHttp(new Uri(_baseAddress + "/token"));
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";

var data = new StringBuilder();
data.Append("grant_type=password&");
data.Append("username=User&");
data.Append("password=Password");

var content = Encoding.UTF8.GetBytes(data.ToString());
request.ContentLength = content.Length;
var requestStream = await request.GetRequestStreamAsync();
requestStream.Write(content, 0, content.Length);

var authenticationResponse = await request.GetResponseAsync();
var responseStream = authenticationResponse.GetResponseStream();
var streamReader = new StreamReader(responseStream);

var token = JsonConvert.DeserializeObject<Token>(streamReader.ReadToEnd());

request = WebRequest.CreateHttp(new Uri(_baseAddress + "/api/blogs"));
request.Headers = new WebHeaderCollection()
{
{ "Authorization", "Bearer " + token.access_token }
};

var apiResponse = await request.GetResponseAsync();

Assert.That(((HttpWebResponse)apiResponse).StatusCode == HttpStatusCode.OK);

requestStream.Close();
responseStream.Close();
authenticationResponse.Close();
apiResponse.Close();

The CreateHttp method retrieve an object of type WebRequest, that is used to compose the request with the credentials in the header.

As you can see, is a low level class, where we need to compose the data header by composing the parameters in a string.

The header is then witten in the request stream, retrieved with the GetRequestStreamAsync method.

With the GetResponseAsync we submit the request to the server and we receive the result; If all is fine, in the response we have the access token, and we can use it in another request to get the data.

WebClient

Also this class was introduced in .NET 2.0 framework, it’s an helper for the WebRequest class and the purpose is to give a more confortable interface to the developers.

Effectively, the authetication code looks more pretty that above:

using (var webClient = new WebClient())
{
webClient.Headers = new WebHeaderCollection()
{
{ "Content-Type", "application/x-www-form-urlencoded" }
};

var content = new NameValueCollection()
{
{ "grant_type", "password" },
{ "username", "User" },
{ "password", "Password" }
};

var response = webClient.UploadValues(_baseAddress + "/token", content);
var token = JsonConvert.DeserializeObject<Token>(Encoding.UTF8.GetString(response));

webClient.Headers = new WebHeaderCollection()
{
{ "Authorization", "Bearer " + token.access_token }
};

response = webClient.DownloadData(_baseAddress + "/api/blogs");

var results = JsonConvert.DeserializeObject<IEnumerable<Blog>>(Encoding.UTF8.GetString(response));
Assert.IsNotNull(results);
}

As you can see, for the header parameters we can use a NameValueCollection because the WebClient class has a UploadValues method that accept this object type and internally deals with transforming of the NameValueCollection into a string before to pass it to the WebRequest class.

Then, the DownloadData internally calls the BeginGetResponse of the WebRequest class.

HttpClient

It’s the newer class introduced in the version 4.0 of the framework and is the easier to use; it’s a replacement of the WebClient and internally it also uses the WebRequest class.

We have to create a new instance of the HttpRequestMessage class and define the content of it with KeyValuePair objects that contains the credentials of the client.

Then, with the SendAsync method we can send the request and get the response with the relative content.

using (var httpClient = new HttpClient())
{
httpClient.BaseAddress = new Uri(_baseAddress);
var request = new HttpRequestMessage(HttpMethod.Post, "/token")
{
Content = new FormUrlEncodedContent(new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("grant_type", "password"),
new KeyValuePair<string, string>("username", "User"),
new KeyValuePair<string, string>("password", "Password")
})
};

request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
using (var authenticationResponse = await httpClient.SendAsync(request))
{
if (authenticationResponse.StatusCode == HttpStatusCode.OK)
{
var content = await authenticationResponse.Content.ReadAsStringAsync();
var token = JsonConvert.DeserializeObject<Token>(content);

request = new HttpRequestMessage(HttpMethod.Get, "/api/Blogs");
request.Headers.Add("Authorization", "Bearer " + token.access_token);

using (var apiResponse = await httpClient.SendAsync(request))
{
Assert.AreEqual(apiResponse.StatusCode, HttpStatusCode.OK);
}
}
}
}

So, the HttpClient is a new implementation of the WebClient, with more features.

Finally, if we don’t have legacy software that is implemented with a older version of .NET framework, the right choice to implement a client with an OAuth authentication is the HttpClient.

 

 

Advertisements
OAuth authentication client with .NET

Managing OAuth 2 authentication with Swagger

In this post I want to talk about a product that could help us to produce documentation about the Web API services implemented in our application.

Swagger is a popular framework that once installed in an ASP.NET application is able to produce documentation about all the Web API implemented in the project.

Furthermore it give us a lot of flexibility and is possible to add some custom filters in order to change the standard behaviours; for example add the OAuth authentication management for the protected applications.

So let’s go to view the steps necessaries to install and configure this framework.

Configuration

The first step is install the package in our project and we can do that with nuget:


Install-Package Swashbuckle -Version 5.6.0

Now we need to add the Swagger configuration in the startup.cs file:


config.EnableSwagger(c =>
{
c.SingleApiVersion("v1", "BaseSPA.Web");
c.OperationFilter<SwaggerFilter>();
c.PrettyPrint();
c.IgnoreObsoleteActions();
}).EnableSwaggerUi();

In the configuration we define the description of the project, we says that we want json in prettify format and we want to ignore obsolete actions.

Furthermore we register a SwaggerFilter, that is a custom filter used to manage the OAuth authentication.

This is the SwaggerFilter implementation:


public class SwaggerFilter: IOperationFilter
 {
 public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
 {
 var toBeAuthorize = apiDescription.GetControllerAndActionAttributes<AuthorizeAttribute>().Any();

if (toBeAuthorize)
 {
 if (operation.parameters == null)
 operation.parameters = new List<Parameter>();

operation.parameters.Add(new Parameter()
 {
 name = "Authorization",
 @in = "header",
 description = "bearer token",
 required = true,
 type = "string"
 });
 }
 }
 }

First of all we need to implement the IOperationFilter interface with the Apply method.

In this method we check the actions protected with the Authorize attribute; for these, we add a new Authorization parameter that we’ll be showed in the Swagger UI and will be used to set the bearer token.

Test Web API

After compiling the project, we can access the url of the application and append the term swagger at the end of that, like this:


http://localhost/swagger

This is what will be showed:

swagger2

If we open one of the actions available, we notice the Authorization attribute that we have configure above:

swagger5

Now what we need is the bearer token to send to the action and we can retrieve it with Postman; we have to send a post request to the token endpoint configured in the application like this:

swagger1

I send a request with my username, password and grant_type keys and I specify the content type as x-www-form-urlencoded as well.

The response contains the access_token and I can copy it in the field in the swagger UI:

swagger3

That’s all, by sending the request, the application recognize me and it send me the response.

You can find the source code here.

 

 

 

 

 

Managing OAuth 2 authentication with Swagger