Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

How to integrate ApiFrame in ASP.NET Web API Application

0.00/5 (No votes)
3 May 2014 1  
Guidelines on how to integrate ApiFrame in Web API application

Introduction

This article will provide some guidelines on how to integrate ApiFrame into ASP.NET Web API project. ApiFrame is a simple .NET library that provides support for implementing Web API security (HMAC Authentication), exception handling, and versioning of Web API methods. The library is like a plugin-component that you can easily integrate into your application. You will find the source code and information related to ApiFrame at this code project article.

ApiFrame : A simple library for Web API security, exception and versioning[^]

I will walk you through a simple Web API sample application that implements POST and GET method for demonstrating Authentication, Authorization, Versioning and Exception Handling. Also, I will take you through how to consume the service from an API Client.

Guidelines: How to integrate API Frame in Web API Project

First, Let us create a sample application.

  1. Open Visual Studio 2012
  2. Create a new ASP.NET MVC 4 Web Application
  3. Select Web API project template

Installation

To install ApiFrame, run the following command in the Package Manager Console

Alternate, the library can be referenced in your project through Nuget Package Manager. In the solution explorer, Select the Web API project -> Right click and Open “Manage Nuget Packages…” -> Search for “ApiFrame” online. You will get the following and Click the install button, this will add API frame to your project.

Configuration

If you are implementing Authentication and Authorization through ApiFrame, then it is required to implement the following interface in your application.

  • IApiInception

For demo purpose let’s do the following in the Web API Project

  1. Create a new folder named “ApiFrameConfig”
  2. Inside the new folder
    • Create a class “ApiInception” that Implements “IApiInception”
    • Create a class “ApiException” that implements “IApiException”

Implementing IApiInception

This interface exposes three methods. The implementation of GetApplicationToken()in you project depends on your business model. If you are exposing the API service to a number of customers then it is required to have an access token and a secret token attached to each customer. Generally, access token and secret token is created at the time of registration and the same is share with the customer for integrating the client application to communicate with the service. If the service is exposed to a single customer then this configuration can be added to Web.config file. AuthScheme is the Authorization Scheme, this can be a common label that you keep it Web.Config or if you would like to attach an abbreviated name for each of you customer then you can use this property. It’s up to your choice but this piece of information is also validated by the library. So, AuthScheme is another piece of information you will need to share with the client.

For the demo purpose, I have the following Implementation in my sample.

public ApiApplicationToken GetApplicationToken(string accessToken)
{
    return new ApiApplicationToken()
    {
        AuthScheme = "HMAC",
        AccessToken = "d85aa01c-cf92-4f1e-9862-638fa4ae37b4",
        SecretToken = "06fb3823-b8cc-462b-b855-f655d49eb3e2"
    };
}

Authentication is based on username and password. Ideally, the below method in your project will call the service/data access layer to check if the given user name and password is valid. For implementing this method, an access token and a secret token should be attached to each existing user. If the username and password is valid then the method should returns a user token as shown in the code sample below. This user tokens are used for authorization purpose. It’s up to the client application to preserve the tokens and use it for issuing a subsequent request to access an authorized resource. ApiFrame supports Role based access in addition. The Role property can be empty if you application doesn’t use Roles based access.

The below code is for demo purpose.

public ApiUserToken GetUserToken(string username, string password)
{
    if (username == "demo" && password == "demo123")
    {
        return new ApiUserToken()
        {
            AuthScheme = "HMAC",
            AccessToken = "94d05acb-54de-4e39-9303-3764cabcaf18",
            SecretToken = "88a10072-5fa9-4a8d-b9ac-42966d8da4bc",
            Name = "DemoUser",
            UserId = "001",
            Roles = "Users"
        };
    }

    return null;
}

The below method is for Authorization. ApiFrame calls this method on authorization by passing the access token of a user as a input parameter to the method. In the real application, this method should call a service or data access method to query the database to fetch the user details by access token. The method constructs a ApiUserToken with the user details and returns the token.

public ApiUserToken GetUserToken(string accessToken)
{
    if (accessToken == "94d05acb-54de-4e39-9303-3764cabcaf18")
    {
        return new ApiUserToken()
        {
            AuthScheme = "HMAC",
            AccessToken = "94d05acb-54de-4e39-9303-3764cabcaf18",
            SecretToken = "88a10072-5fa9-4a8d-b9ac-42966d8da4bc",
            Name = "DemoUser",
            UserId = "001",
            Roles = "Users"
        };
    }

    return null;
}

Implementing IApiException

Exceptions can be caught by implement this interface.

    public class ApiException : IApiException
    {
        public void LogMessage(Exception exception)
        {
            throw new NotImplementedException();
        }
    }

Once, you have done implementing the interfaces, it is required to add the following configuration in the project to injects the implementation (dependencies) into the library. In the Global.asax file, Include the below code in the Application_Start()

// ApiFrameConfiguration
ApiObjectFactory.RegisterType<IApiInception, ApiInception>();
ApiObjectFactory.RegisterType<IApiException, ApiException>();
ApiObjectFactory.RegisterType<IApiSignature, ApiSignature>();

Sample Web API methods

In you are interested in versioning you Web API methods, ApiFrame provides an option for versioning using MVC Areas or using namespace. Let’s try using Areas.

Create a new MVC Area and name it as “V1” and do the following configuration in WebApiConfig.cs file. That it’s, you are almost done with setting up versioning your web API methods and rest you will have to play with the routing.

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Services.Replace(typeof(IHttpControllerSelector), new ApiControllerSelector(config));
        }
    }

Create the following model in V1

     public class AccessModel
    {
        public string AccessToken { get; set; }
        public string SecretToken { get; set; }
    }

Add a new controller to the project and name it “DemoController”. Frame the DemoController with the “ApiException” attribute to allow ApiFrame to handle the exception for you.

    [ApiException]
    public class DemoController : ApiController
    {

    }

Add the following methods to the DemoController. Let’s create the following methods for demo.

  • SignIn - POST method for Authentication demo
    • Relative route : /demo/signin
  • GetMessage - GET Method for Authorization demo
    • Relative route : /demo/getmessage

You will notice that the below SignIn method is framed with ApiAuthentication filter attribute. Similarly, GetMessage with ApiAuthorization filter attribute. This filter attributes handles the authentication and authorization by calling the injected methods implemented by IApiInception.

[HttpPost]
[ApiAuthentication]
public AccessModel SignIn()
{
    return new AccessModel
    {
        AccessToken = "94d05acb-54de-4e39-9303-3764cabcaf18",
        SecretToken = "88a10072-5fa9-4a8d-b9ac-42966d8da4bc"
    };
}

[HttpGet]
[ApiAuthorization(Roles = "Users")]
public string GetMessage()
{
    string user = ((ApiIdentity)HttpContext.Current.User.Identity).Name;
    return string.Format("Server Message :This is an Authorized Request - LoggedIn User:{0}", user);
}

Update the default route in V1AreaRegistration class.

public override void RegisterArea(AreaRegistrationContext context)
{
    context.Routes.MapHttpRoute(
        "V1_default",
        "{area}/{controller}/{action}/{id}",
        new { id = UrlParameter.Optional }
    );
}

Run the application and you will see the below screen. My sample Web API service is running at URL localhost:6360

The API client should use the same URL to communicate with the service.

Sample API client

For the demo purpose, let’s consume the Web API service from a console application.

  1. Open Visual Studio 2012
  2. Create a Console Application
  3. Add reference to System.Net.Http assembly
  4. Install the following through Nuget Packet Manager
    • ApiFrame
    • Json.NET

We need the following initial settings before we call the API service

// Service Url
string serviceUrl = "http://localhost:6360/";

// Uri version
string apiVersion = "v2";

// Signature Configuration
ApiObjectFactory.RegisterType<IApiSignature, ApiSignature>();

ApiFrame uses HMAC-SHA256 algorithm to calculate the signature. Same algorithm need to use in both ends (client and server). For this we need the above signature configuration in client.

Server will identify the client with the token and the following configuration is required and the tokens should be the same as what is stored in the server.

// Token Configuration
const string AuthScheme = "HMAC";
const string AccessToken = "d85aa01c-cf92-4f1e-9862-638fa4ae37b4";
const string SecretToken = "06fb3823-b8cc-462b-b855-f655d49eb3e2";

Follow the steps to check the SignIn API service

  1. Read the username and password through the console
  2. Create a post data with Username and Password
  3. Create the request token with the required parameters for the service call
  4. Create an instance of ApiClientGateway by passing the service url
  5. Call the Execute method of ApiClientGateway by passing the request token
// Authentication - Sing-in demo - START
Console.WriteLine("\n Authentication -> Sign-in demo - START");
Console.Write("\n\n Enter the Username:");
string userName = Console.ReadLine();
Console.Write(" Enter the Password:");
string password = Console.ReadLine();

string postData = string.Format("Username={0}&Password={1}", userName, password);

ApiRequestToken requestToken = new ApiRequestToken()
{
    Verb = HttpMethod.Post,
    RelativeUrl = string.Format("{0}/demo/signin", apiVersion),
    AccessToken = AppAccessToken,
    SecretToken = AppSecretToken,
    AuthScheme = AuthScheme,
    Content = postData
};

ApiClientGateway apiClientGateway = new ApiClientGateway(serviceUrl);
AccessModel signInResult = null;
try
{
    signInResult = apiClientGateway.Execute<AccessModel>(requestToken);

    if (signInResult != null)
    {
        Console.WriteLine("\n Response from server");
        Console.WriteLine("\n AccessToken:" + signInResult.AccessToken);
        Console.WriteLine(" SecretToken:" + signInResult.SecretToken);
        Console.WriteLine("\n Successfully Authenticated! This is ApiAuthentication Test");
    }
}
catch (ApiRequestException ex)
{
    Console.WriteLine(ex.ErrorResponseMessage.
        Content.ReadAsStringAsync().Result);
}

// Sing-in demo - END

When calling the sign-in service, the server returns a token (Access token and secret token) on successful authentication. This token is preserved and used for subsequent service call. Below is the sample that call an authorized API service method that return a private message. Let’s the use the received token to make a next service call to get the private message

// Authorization -> GetMessage demo - Start

Console.WriteLine("\n Authorization demo -> GetMessage - START");
Console.Read();

if (signInResult != null)
{
    requestToken = new ApiRequestToken()
    {
        Verb = HttpMethod.Get,
        RelativeUrl = string.Format("{0}/demo/GetMessage", apiVersion),
        AccessToken = signInResult.AccessToken,
        SecretToken = signInResult.SecretToken,
        AuthScheme = AuthScheme
    };

    string messageResult = string.Empty;

    try
    {
        messageResult = apiClientGateway.Execute(requestToken);

        if (!string.IsNullOrEmpty(messageResult))
        {
            Console.WriteLine("\n This is ApiAuthorization test");
            Console.WriteLine("Server Response :" + messageResult);
        }
    }
    catch (ApiRequestException ex)
    {
        Console.WriteLine(ex.ErrorResponseMessage.
            Content.ReadAsStringAsync().Result);
    }
}

Console.Read();
// Authorization -> GetMessage demo - End

On exception, service returns an exception of type ApiRequestException. Below shown is the screen shot of service call for signin with wrong credential.

    catch (ApiRequestException ex)
    {
        Console.WriteLine(ex.ErrorResponseMessage.
            Content.ReadAsStringAsync().Result);
    }

API Versioning demo

In the Web API project, Let’s create a new version of “DemoController” and add new version of Sign-In and GetMessage service.

  1. Create a new MVC Area named “V2”
  2. Add a new “DemoController” and “AccessModel”
  3. Copy the SignIn and GetMessage service from version V1
  4. Update the GetMessage service to contain a new version of message
  5. Run the application and keep the service up and running

In the API client, Update the apiVersion and run the application. The authorized service "GetMessage" will now return a new version of updated message.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here