Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
ShilpaVij
Advisor
Advisor
There are times when you want to store data for retrieval at runtime—non-expiring data that shouldn't be hard-coded in your API proxy logic. Key value maps (KVMs) are ideal for this. A KVM is a custom collection of key/value String pairs that is either encrypted or unencrypted. To explain the scenario, I will take an example where you want to verify the API Key and based on the key construct the authorization header and send the username and password to connect to the backend.

In this blog, I will explain, when we use Key Value Maps and how they work in SAP Cloud Platform API Management.

When to use Key Value Map



  • Specific places in your code require different values at runtime.

  • Sensitive data needs to be passed without hard-coding it.

  • You want to store values that don't expire like a cache might.


KVMs have scope


Scope means "where a KVM is available." KVMs can be created at the following scopes: organization, environment, and API Proxy.

For example, if only one API proxy requires data in a KVM, you can create the KVM at the API Proxy scope, where only that API proxy can access the data.

Or you may want all API proxies in your test environment to have access to a key value map, in which case you'd create a key value map at the environment scope. Proxies deployed in the "prod" environment cannot access KVMs in the "test" environment scope. If you want the same KVM keys to be available in production, create a parallel KVM scoped to the "prod" environment.

If you want all proxies in all environments to access the same KVM, create the KVM at the organization scope.

Let’s get started!


Now let’s go to the SAP API Management Service. From your SAP Cloud Platform cockpit, navigate to the list of services and locate API Management Service. Click on “Access API Portal”. It is a good idea to add the SAP API Management as a bookmark to your browser now.



Click on Develop and Navigate to API Providers



Create API Provider and fill in the following details

Note that the hostname and the host port correspond to the actual host and port of the system.

Since it is a cloud system hence do not select on-premise check box.



Navigate to Connection and enter the details.



Lastly, navigate to the CATALOG SERVICE SETTINGS tab, and setup the catalog service as defined below (or adapt it to your environment).

Note: By providing the Catalog Service Settings, you can search and explore the OData APIs that is available in the specific SAP Gateway account. In Service Collection URL the relative path to OData Catalog Service Collection URL can be provided which is /sap/opu/odata/IWFND/CATALOGSERVICE/ServiceCollection

Currently, OData V4 services are not listed for Service Catalog option.

In case you are connecting to a non-default SAP Client then you can specify the sap-client information by using the SAP query parameters (sap-client={your_gateway_client) e.g /sap/opu/odata/IWFND/CATALOGSERVICE/ServiceCollection?sap-client=001 ( where 001 is the sap-client that you would like to connect to).



Before we create API proxy we, will create a key-value map where we will store username and password for ES5 backend system.

In this scenario, we will use the postman to create a KVM

Note: Install postman application as a chrome add-in if not done yet.



 

Navigate to postman or any REST Tool and

  1. Set HTTP Verb to HEAD

  2. Enter URL: https://<apiportalhost>/apiportal/api/1.0/Management.svc/KeyMapEntries (replace <apiportalhost>)


Provide Username and Password.



  1. Fetch the x-csrf-token.


Go to response headers and copy value of header X-CSRF-Token



Create new tab, clone the request, change HTTP Verb to POST and change HTTP Header X-CSRF-Token to previously copied value

Navigate to “Body”, switch to raw, set Content-Type to “application/json” and copy json snippet and replace values for username / password with your values ES5 values.
{
"name":"ES5ENC",
"encrypted":true,
"keyMapEntryValues":[
{
"name":"username",
"value":"<username>",
"map_name":"ES5ENC"
},
{
"name":"password",
"value":"<password>",
"map_name":"ES5ENC"
}
]
}

Press send and check that status is HTTP 201 created.

 

Navigate to APIs and create a new API Proxy alternatively you can copy the API proxy and save and deploy it.





Navigate to policy editor and click on edit.

To the pre-flow of target endpoint add a key value map policy from right-hand side.

Map Identifier is the map name which we have created and username and password are picked and assigned to a variable.
<!-- Key/value pairs can be stored, retrieved, and deleted from named existing maps by configuring this policy by specifying PUT, GET, or DELETE operations -->
<!-- mapIdentifier refers to the name of the key value map -->
<KeyValueMapOperations mapIdentifier="ES5" async="true" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt">
<!-- PUT stores the key value pair mentioned inside the element -->
<Get assignTo="basicAuth.username">
<Key>
<Parameter>username</Parameter>
</Key>
</Get>
<Get assignTo="basicAuth.password">
<Key>
<Parameter>password</Parameter>
</Key>
</Get>
<Scope>environment</Scope>
</KeyValueMapOperations>

Also, attach Basic Authentication policy to pass username and password as a header to the backend.
<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="basicAuth.username"></User>
<!-- for Encode, Password element can be used to dynamically populate the password value -->
<Password ref="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>

Save and Deploy the proxy.

Navigate to test console, select the API and without giving authentication send the request.



Note: To encrypt the confidential details like password etc. we can also use the Encrypted Key Value Map. Stay tuned for more update.

Further Reads



  • API Security Best Practices Blog Series

  • For more blogs on SAP Cloud Platform, API Management visit us at SCN

4 Comments