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.

 

 

 

 

 

Advertisements
Managing OAuth 2 authentication with Swagger

Consume Web API OData with ODataAngularResources

One month ago, I wrote this post about the odata services and how we can consume those with the $http factory of Angularjs.

This approach is not wrong but is not smart at all, because we have to write every query for any call that the application needs to do, and is not flexible.

What we could do is write our custom library that deal with the odata url format and it expose some fluent methods that the components of the application can call; in this way we have a layer between the angular services and the odata controller and the code should be more readable.

Anyway, write a library like that is not very easy and require a lot of amount of time.

The solution of these problems is a library already implemented that we can use directly in our angular application, that is ODataAngularResources.

This is a lightweight library that allow writing the OData queries with fluent methods.

What I’ll go to do is leverage this library for the queries and implement a custom service to manage the entities saving.

ODataResource factory

The first factory that I want to implement is an object that wrap the basic ODataResources module and expose the CRUD operations of the entity.

First of all, I need to install the library, and you can refer to the GitHub project for any detail.

Than, I can start with the implementation and creating the new module:


(function(window, angular) {
'use-strict';
angular.module('odataResourcesModule', ['ui.router', 'ODataResources'])

.factory('odataResource', function ($odataresource, $http, $q) {

function odataResource(serviceRootUrl, resourcePath, key) {
this.serviceRootUrl = serviceRootUrl;
this.resourcePath = resourcePath;
this.key = key;

this._odataResource = $odataresource(serviceRootUrl + '/' + resourcePath, {}, {}, {
odatakey: key,
isodatav4: true
});

angular.extend(this._odataResource.prototype, {
'$patch': function () {
var defer = $q.defer();

var req = {
method: 'PATCH',
url: serviceRootUrl + '/' + resourcePath + '(' + this.Id + ')',
data: this
};

$http(req).then(function (data) {
defer.resolve(data);
}, function (error) {
defer.reject(error);
});

return defer.promise;
}
});
}

.....

The factory has a constructor where I pass three parameters, the ServiceRootUrl that is the first part of the url (in my case odata), the resourcePath that identify the entity (Blogs) and the key of the table.

Then I configure the $odataresource with these parameters and I setup the odata v4 as well.

At the end I extend the OdataResource prototype because this library doesn’t provide the implementation for the PATCH verb, I need to implement it with my custom function.

So far so good, now I want to expose some methods to queries the resource or retrieve a single entity:


odataResource.prototype.getResource = function () {
return this._odataResource.odata();
}

odataResource.prototype.get = function (id) {
var defer = $q.defer();

this._odataResource.odata().get(id, function (data) {
data._originalResource = angular.copy(data);
defer.resolve(data);
}, function (error) {
defer.reject(error);
});

return defer.promise;
}

With the getResource method I implement a getter for the resource and allow the caller to execute the queries.

The get method deserves a particular explanation, once the single entity is retrieved, I make copy of the original entity and assign that to a new private property named _originalResource.

This will allow me two check the values that will be changed on the entity, and compose the object that will be sent with the patch method.

Now I can implement the others methods to add, update and delete the entity:


odataResource.prototype.new = function () {
return new this._odataResource();
}

odataResource.prototype.add = function (resource) {
var defer = $q.defer();

resource.$save(function (data) {
data._originalResource = angular.copy(data);
defer.resolve(data);
}, function (error) {
defer.reject(error);
});

return defer.promise;
}

odataResource.prototype.update = function (resource) {
var defer = $q.defer();

var self = this;
resource.$patch().then(function () {
self.get(resource[self.key]).then(function (data) {
defer.resolve(data);
});
}, function (error) {
defer.reject(error);
});

return defer.promise;
}

odataResource.prototype.delete = function (resource) {
var defer = $q.defer();

resource.$delete(function (data) {
defer.resolve(data);
}, function (error) {
defer.reject(error);
});

return defer.promise;
}

Like the get method, I do a copy of the entity in the add method as well.

Now I have a factory that is able to query Web API OData services and manage the crud operations and I can proceed with some business logic.

ODataGenericResource factory

The first step is define the new factory:


.factory('odataGenericResource', function ($q, odataResource) {

function odataGenericResource(serviceRootUrl, resourcePath, key) {
this.odataResource = new odataResource(serviceRootUrl, resourcePath, key);
}

In the constructor I create a new instance of the ODataResource factory, in order to leverage the methods implemented above.

Based on the id parameter, now I implement a get method that will create a new resource or perform a get from a Web API OData service:


odataGenericResource.prototype.get = function (id) {
if (id === '') {
var defer = $q.defer();
defer.resolve(this.odataResource.new());

return defer.promise;
} else {
return this.odataResource.get(id);
}
}

If an external service will call this method with an empty id will receive a new resource, otherwise will receive the entity, if exists.

Now I need to implement the save method:


odataGenericResource.prototype.isChanged = function (resource) {
var isChanged = false;
for (var propertyName in resource) {
if (isEntityProperty(propertyName) && resource._originalResource[propertyName] !== resource[propertyName]) {
isChanged = true;
}
}

return isChanged;
}

odataGenericResource.prototype.getObjectToUpdate = function (resource) {
var object = this.odataResource.new();
object[this.odataResource.key] = resource[this.odataResource.key];

for (var propertyName in resource) {
if (isEntityProperty(propertyName) && resource._originalResource[propertyName] !== resource[propertyName]) {
object[propertyName] = resource[propertyName];
}
}

return object;
}

odataGenericResource.prototype.save = function(resource) {
if (!resource._originalResource) {
return this.odataResource.add(resource);
} else if (this.isChanged(resource)) {
var object = this.getObjectToUpdate(resource);
return this.odataResource.update(object);
} else {
var defer = $q.defer();
defer.resolve(resource);

return defer.promise;
}
}

I need some methods, to check the state of the entity.

The IsChanged method check if any property of the entity is changed, leveraging the _originalResource property.

The second method prepare the effective object to save, with only the properties that has been changed.

The save method check if the entity is new (it doesn’t have the _originalResource property) or not; based on that, it will be added or saved.

The delete method doesn’t have particular stuff and we can now take a look at the using of this factory in the application.

Application

I can use this factory in any angular module that needs to manage crud operations for an entity.

For example, in a blogsModule, I can define a factory like this:


(function (window, angular) {
'use-strict';
angular.module('blogsModule', ['ui.router', 'odataResourcesModule'])
.factory('blogsService', function ($http, odataGenericResource) {
return new odataGenericResource('odata', 'Blogs', 'Id');
})

And now in the controller:


.controller('blogsCtrl', function ($scope, $state, blogsService) {

$scope.new = function() {
$state.go("home.blog", { id: null });
};

$scope.detail = function(id) {
$state.go("home.blog", { id: id });
};

$scope.Blogs = blogsService.getOdataResource().query();
})
.controller('blogsDetailCtrl', function ($scope, $state, blogsService) {
var load = function (id) {
blogsService.get(id).then(function(data) {
$scope.Blog = data;
});
};

$scope.save = function () {
blogsService.save($scope.Blog).then(function(data) {
load(data.Id);
});
}

$scope.delete = function () {
blogsService.delete($scope.Blog).then(function () {
$scope.close();
});
};

$scope.close = function () {
$state.go("home.blogs");
};

load($state.params.id);
});

With few lines of code I can manage the calls to a Web API OData service, with the possibility do fluent odata queries.

You can find the source code here.

Consume Web API OData with ODataAngularResources