Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 

Introduction


MAC (Hash message authentication code) is a specific type of message authentication code involving a cryptographic hash function and a secret cryptographic key. Which can be used to simultaneously verify both the data integrity and the authenticity of a message. This blog post provides a mechanism on how to integrate such type of interfaces or webhooks into SAP Cloud system using SAP Cloud API Management.


Image result for hmac

Limitation: CPI inbound http adapter does not allow for a “no authorisation” policy nor does it have capability for other authorisation methods beside certificates/user-based authorisation but this can be resolved through API Management, which offers a great number of possibilities around policies.

Background


This blog post will illustrate the use case of API Management functioning as an intermediary between a source system, that triggers webhook notification secured with HMAC, and CPI, and getting in charge of the security between the systems. We use API management to authenticate the message and forward it to CPI then CPI does complex orchestration that is required to integrate into SAP Gigya and Marketing Cloud systems.

The objective of this blog post is to show how to verify HMAC-SHA1 Hash signature of sender system and generate and outbound call to CPI with user authentication.

 

API Policy Flow

The following diagram depicts the policy flow template that you need to create in SAP API Management to authenticate the message using HMAC-SHA1 and forward the message to SAP  CPI Layer for complex orchestration.



Step 01 - vmBasic Policy

Retrieve Target system user/passwords from secure value mapping and save it into a parameter that can then be used on Policy Flow.












<KeyValueMapOperations async="true" continueOnError="false" enabled="true" mapIdentifier="CPI" xmlns="http://www.sap.com/apimgmt">

<!-- The variable to which the retrieved value should be assigned. Use private for encripted key value map -->

    <Get assignTo="private.basicAuth.username">

        <Key>

            <Parameter>username</Parameter>

        </Key>

    </Get>

    <Get assignTo="private.basicAuth.password">

        <Key>

            <Parameter>password</Parameter>

        </Key>

    </Get>

    <Scope>environment</Scope>

</KeyValueMapOperations>






Webhook security 

Step 02 - extJson

Allows to extract Json payload or a particular node and save it into a variable.















<ExtractVariables async="true" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt">

    <!-- the source variable which should be parsed -->

    <JSONPayload>

        <Variable name="jsonPayl">

            <JSONPath>$</JSONPath>

        </Variable>

    </JSONPayload>

    <Source clearPayload="false">request</Source>

    <VariablePrefix>myprefix</VariablePrefix>

</ExtractVariables>






Step 03 - vmPartner

Retrieve partner key from secure value mapping and save it into a parameter















<KeyValueMapOperations async="true" continueOnError="false" enabled="true" mapIdentifier="SourceSystem" xmlns="http://www.sap.com/apimgmt">

    <Get assignTo="private.partner">

        <Key>

            <Parameter>partner</Parameter>

        </Key>

    </Get>

    <Scope>environment</Scope>

</KeyValueMapOperations>






Step 04 - checkHash

Indicate the script name that will do the hash verification. In this case we used a Phyton script.












<Script async="false" continueOnError="false" enabled="true" timeLimit="200" xmlns='http://www.sap.com/apimgmt'>

    <!-- Resource URL refers to the main script file that should be run -->

    <ResourceURL>py://helper2.py</ResourceURL>

</Script>






Check the received hash string with our partner key. If they do not match it will raise an error, finalising the flow process.















import hashlib

import hmac

import base64


def make_digest(message, key):

    digester = hmac.new(base64.b64decode(key), message, hashlib.sha1)

    signature1 = digester.digest()

    signature2 = base64.b64encode(signature1)   

    return signature2;


message = "";

message = flow.getVariable("myprefix.jsonPayl");

webhookHash = flow.getVariable("request.header.<hashName>");

result = make_digest(str(message), flow.getVariable("private.partner"));

flow.setVariable("hash",result);

if (result != webhookHash):

    raise NameError("invalid origin")






CPI Security.

Step 05 - basicAuthentication

Set the basic authentication for the target system call, with the secured parameters defined on first step:












<BasicAuthentication async='true' continueOnError='false' enabled='true' xmlns='http://www.sap.com/apimgmt'>

    <!-- Operation can be Encode or Decode -->

    <Operation>Encode</Operation>

    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>

    <!-- for Encode, User element can be used to dynamically populate the user value -->

    <User ref='private.basicAuth.username'></User>

    <!-- for Encode, Password element can be used to dynamically populate the password value -->

    <Password ref='private.basicAuth.password'></Password>

    <!-- Source is used to retrieve the encoded value of username and password. This should not be used if the operation is Encode-->

    <Source>request.header.Authorization</Source>

    <!-- Assign to is used to assign the encoded value of username and password to a variable. This should not be used if the operation is Decode -->

    <AssignTo createNew="false">request.header.Authorization</AssignTo>

</BasicAuthentication>






Test example on API Management

We can try the application directly on API Management by specifying the Webhook JSON payload and the security header hash.



API returns a successful response with the message set on CPI flow.

We can see on response headers SAP_MessageProcessingLogID of the message processed on SAP CPI.



In second test case we had altered the message data modifying the event id on the payload which invalidates HMAC signature.

API Management returns an error 500 to source system with the exception programmed on script validation step.



 

Conclusion:

API Managements offers a broad number of possibilities around security policies for API creation, which can also be used to set a bridge to more complex orchestration between systems and SAP Cloud Platform Integration, thus allowing to overcome CPI limitations regarding authorisation methods.
In this blog post we had explored one of such cases, using API Management to verify HMAC-SHA1 hash and act as a security handler between a source system and CPI.
3 Comments
Labels in this area