Integrating WSO2 API Manager with a HMAC Secured Backend

  • By Nadeesha Gamage
  • 30 Oct, 2017

Introduction

API security is an inherent part of API management. Even though API management solutions provide their own security and authentication mechanisms for APIs that are exposed, most backend systems also maintain their own authentication mechanisms to secure services that are exposed for consumption. These include security mechanisms, such as basic authentication, digest authentication, and Hash-based Message Authentication Code, or HMAC-based authentication. Hence, it’s important for an API management solution to work with these backend authentication mechanisms and provide a unified authentication protocol to its API consumers. HMAC is a common practice that’s used by organizations to secure APIs. This article will focus on how an HMAC protected backend service can be exposed via WSO2 API Manager.

API Authentication

API authentication is one of the most important capabilities of an API management solution. Without proper authentication for APIs an organization would not be in a position to securely expose its APIs for consumption. Even though an organization may provide a unified API portal and a gateway that exposes APIs from multiple business units, each of these business units may follow its own API authentication mechanisms and policies. Hence, it’s important for an organization to hide these authentication complexities from API consumers whenever possible and provide a common and standardized API authentication mechanism across all APIs. In such a case, the API management tool would do the required identity bridging between the request that comes from the application to the request that goes out to the backend. This process is illustrated in Figure 1.

Figure 1

WSO2 API Manager provides the capability for an API publisher to configure a backend secured via basic or digest authentication. This option is provided in the API Publisher wizard of the API Manager [1] [2]. API creators/publishers can seamlessly integrate with a backend that’s secured with basic or digest auth using this mechanism. However, integrating with a backend that is secured via HMAC is not provided as an option in the API Publisher wizard. This is because HMAC-based authentication has many different types of implementations and it would not be possible to do a generalized implementation that would support all types of HMAC authentication. Even though integrating with a HMAC protected backend is not provided via the API Publisher UI, it is possible to write a mediation extension in the API Manager to achieve this integration. The section below would look at this in more detail.

Mediation Extensions of API Manager

Mediation extensions allows the API Manager to execute a custom set of message mediations in the message inflow, outflow or the fault flow. Meditation extension can be developed using the WSO2 API Manager tooling component [3]. The tooling component allows API creators to create mediation extensions required for the API and push them to WSO2 API Manager. Imported mediation extension can be attached to an API from the API Manager Publisher wizard. This provides a seamless experience for publishers to extend the existing message mediation flow as required. For this example, we will look at how mediation extensions can be used to create a custom HMAC token that needs to be sent to the backend.

Creation of a HMAC via a mediation extension

  • We will start by downloading and running an instance of WSO2 API Manager. For this example, we will use the API Manager with all profiles running in a single instance. You will also need to download WSO2 tooling for API Manager. Both API Manager and the tooling component required can be downloaded from this link [4].
  • The next step would be to create the required mediation extension that would build the HMAC required to invoke the backend. The mediation extension would invoke a Java class (via a class mediator) to create the required HMAC. Let’s create a mediation extension that depicts the mediation flow in Figure 2. The Synapse configuration for the corresponding mediation extension is given below.

Figure 2

<sequence name="HMACCreator" trace="disable" xmlns="https://ws.apache.org/ns/synapse">
    <property description="Client Id" name="clientId" scope="default" type="STRING" value="hSN3y4iQGUCUfvovakUq5Sq1CTQa"/>
    <property description="Client Secret" name="clientSecret" scope="default" type="STRING" value=":X2doTVRxXD7Q_OlK9ksBPvRBBlUa"/>
    <class description="CustomHMAC" name="com.sample.mediators.CustomHMAC"/>
    <property description="Authorization Header" expression="get-property('Authorization')" name="Authorization" scope="transport" type="STRING"/>
    <property description="Date Header" expression="get-property('Date')" name="Date" scope="transport" type="STRING"/>
</sequence>

Once the HMAC creator meditation extension is done, push it to the API Manager using the WSO2 API Manager tooling component. You can refer to the following documentation that provides a guide on how to create and push a mediation extension to the API Manager [3]. The mediation extension would pass the client key and client secret as two properties to the CustomHMAC class. These two values are preset in the mediation flow; however, it is possible to get these values from the incoming message if required.

<<Info message>>

If you want this HMAC creator to be a global extension, then you can create the mediation extension by creating the extension with the naming pattern WSO2AM--Ext--In and saving the extension in /repository/deployment/server/synapse-configs/default/sequences. In this case, the CustomHMAC sequence would look something like this:

<sequence xmlns="https://ws.apache.org/ns/synapse" name="WSO2AM--Ext--In">
<property description="Client Id" name="clientId" scope="default" type="STRING" value="hSN3y4iQGUCUfvovakUq5Sq1CTQa"/>
    <property description="Client Secret" name="clientSecret" scope="default" type="STRING" value="X2doTVRxXD7Q_OlK9ksBPvRBBlUa"/>
    <class description="CustomHMAC" name="com.sample.mediators.CustomHMAC"/>
    <property description="Authorization Header" expression="get-property('Authorization')" name="Authorization" scope="transport" type="STRING"/>
    <property description="Date Header" expression="get-property('Date')" name="Date" scope="transport" type="STRING"/>
</sequence>

If the sequence is created and added this way the mediation extension would be applied to all APIs that are created through the API Manager.

<<Info message>>
  • The HMACCreator mediation sequence would invoke com.sample.mediators.CustomHMAC java class. This Java class would carry out the required HMAC creation based on the client secret, HTTP method, date, resource path content type (only for POST requests) and the message body (only for POST requests). This HMAC implementation would create the following headers that would be sent to the backend.

Authorization=<Client Key> :<HMAC Digest>

Date=<Date>

The source code of the HMACCreator class can be found in the following GIT Repo [5]. The compiled Jar file of the class mediator is attached with this article. Download and drop the JAR file to /repository/components/lib folder. This HMAC Creator class is written to support HTTP GET and HTTP POST requests. The implementation is given as an example; in most cases, you would have to customize the implementation to suit your own HMAC authentication requirements.

  • lBy default the API Manager drops the ‘Date’ header when it sends a message out to the backend system. In order for API Manager to preserve this header the following configuration needs to be set in /repository/conf/passthru-http.properties and /repository/conf/nhttp.properties

http.headers.preserve=Date

Once this is set and the JAR file has been added to the lib folder as instructed in Step 3, you can restart the server.

  • You can now create an API in the API Manager, which would call a backend that is protected via HMAC authentication. When creating the API ensure you select the HMACCreator mediation extension from the mediation extensions sections in the API Publisher as shown below.
<<Info Message>>

If the mediation extension is created as a global extension, this step is not required and the HMACCreator would be added by default to all the APIs that are created via WSO2 API Manager.

<<Info Message>>

Once the API is created it can be published to the API Gateway. You can now expose your HMAC protected backend services for consumption via the API Manager.

Debugging the Scenario

When working with a scenario like this it is important to have the capability of debugging the mediation extension so it’s easily possible to figure out any issues that are encountered in the HMAC generation process. This scenario can be debugged in multiple ways.

  • Enabling HTTP wire logs in API Manager

It is possible to enable logs of different components to track the behavior of this HMAC mediation extension. You can do this through the API Manager carbon adminstration console that can be accessed via htttp://:/carbon

Once you log into this carbon administration console select the configure tab as shown in the left corner.

When you are inside the logging page search for Org.apache.synapse.transport.http.wire and set the log level to debug. As shown below

Once this is set you can see the actual http message that’s sent out from the API Manager to the backend. This allows a developer to validate the HTTP headers that is sent out from the API Manager to make sure that HMAC is created correctly and the required headers are sent to the backend. Given below is an extract of actual HTTP wire logs logged via the API Manager.

  • Remote debugging the class mediation

It is possible to remote debug the class mediation (HMACCreator) that is invoked by the mediation extension. This would allow a developer to set debug points in the source code and see how the code is getting executed via the API Manager. This can be done by running the HMACCreator in remote debugging mode in your IDE and starting the WSO2 server in debug mode using the following command. In this case, 5005 is set as the remote debug port.

wso2server.sh -debug 5005

Other Ways to Integrate with an HMAC Protected Backend from the API Manager

Mediation extensions are not the only way to configure WSO2 API Manager to integrate with an HMAC protected backend. It is possible to create a custom message handler that can do the same task that’s done via a mediation extension. A handler refers to a fundamental construct that intercepts an API invocation. When an API is created, a set of default handlers are set to the API, which would intercept the message that hits the API. A custom handler can be created, which would generate and include the required HMAC header to the API. This can then be passed to the backend. However, it would not be possible to create or attach a handler to an API via the UI and the developer would be required to set it up as part of the API creation template, which would make the handler apply to all APIs that are created via the API Manager. More information on custom handlers are available at this link [6].

Summary

API authentication is an essential part of the API management story. WSO2 API Manager provides a comprehensive platform that allows the API Manager to integrate with different backend systems that are protected by a myriad security mechanisms. This article demonstrated how an API Manager can integrate seamlessly with an HMAC protected backend service.

[1]https://docs.wso2.com/display/AM210/Basic+Auth

[2]https://docs.wso2.com/display/AM210/Digest+Auth

[3]https://docs.wso2.com/display/AM210/Change+the+Default+Mediation+Flow+of+API+Requests

[4]https://wso2.com/api-management/#download

[5]https://github.com/nadeesha5814/APIManager-HMAC

[6]https://docs.wso2.com/display/AM210/Writing+Custom+Handlers