OAuth 2.0 Authentication for API Management to Connect to CPI
In this blogpost I am going to discuss about how to configure OAuth 2.0 for an API created in SAP API Management. Additionally I will describe how you can use basic authentication to connect to backend (CPI) in the same API.
Create API to Generate Token:
At first, we need to create an API proxy to generate OAuth token.
In resources, add a POST resource named /token
Now, in the policies, in edit mode, we need to add policy OAuth v2.0 for the resource token with stream as Incoming Request.
In policy editor, need to write the below code:
<OAuthV2 async="false" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt"> <Operation>GenerateAccessToken</Operation> <GenerateResponse/> <SupportedGrantTypes> <GrantType>client_credentials</GrantType> </SupportedGrantTypes> </OAuthV2>
Now deploy the API and create a product and application.
Test OAuth Generation:
For testing, you can use Postman or any other similar tool to check whether access_token is being generated.
Here, client_id is the Application Key and client_secret is the Application Secret which you can find from the generated application. I have put grant_type as client_credentials because while generating the access token I have mentioned it.
Create API to Connect to CPI:
Now I am going to create another API to connect to CPI. For that at first I have created a API Provider for CPI. We can use cloud integration type connection or a simple internet type connection. If we create cloud integration type connection, we can provide authentication either basic or OAuth. For OAuth authentication to CPI, tenant administrator can generate a key. To understand how to create this key, you can follow this blogpost
I am not describing how to create an API to connect to CPI in details.
Policies in API to Connect to CPI:
The main challenge is to set up the policy chain for this requirement. The objective is to at first verify the OAuth token and then set up basic authentication for CPI. I have saved the username and password in key value pair.
- OAuth Verification: The first step in the policy chain is to verify the OAuth token generated from the previous API. For that I have added OAuth v2.0 policy at preflow step. In editor I have written:
<OAuthV2 async="false" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt"> <ExternalAuthorization>false</ExternalAuthorization> <Operation>VerifyAccessToken</Operation> <GenerateResponse enabled="true"/><SupportedGrantTypes/> <Tokens/> </OAuthV2>
- Remove Authorization Header: We need to set up basic authentication in later step, before that we need to remove the Authorization header. So I have added Assign Message step with below code:
<!-- This policy can be used to create or modify the standard HTTP request and response messages --> <AssignMessage async="false" continueOnError="true" enabled="true" xmlns='http://www.sap.com/apimgmt'> <Remove> <Headers> <Header name="Authorization"></Header> </Headers> </Remove> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> <AssignTo createNew="false" type="request"></AssignTo> </AssignMessage>
- Get Value from Key Value Pair: I have already saved CPI username and password in a key value pair named CPIInternal, so I have defined key value map operation to extract those value and set in header.
<KeyValueMapOperations mapIdentifier="CPIInternal" async="true" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt"> <Get assignTo="private.username"> <Key> <Parameter>username</Parameter> </Key> </Get> <Get assignTo="private.password"> <Key> <Parameter>password</Parameter> </Key> </Get> </KeyValueMapOperations>
- Perform Basic Authentication: In the next step, I have added basic authentication policy where I am encoding the username and password in Base64 and setting the Authorization header again
<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.username'></User> <!-- for Encode, Password element can be used to dynamically populate the password value --> <Password ref='private.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>
Now update and deploy the API and create product and application.
Testing API to Connect CPI:
I have set up test connection using Postman:
Please note, the client_id and client_secret should the application key and application secret respectively for the application you have created for the API to connect to CPI.
This is how you can set up OAuth Authentication for your APIs created in SAP API Management.
References : https://blogs.sap.com/2016/11/14/oauth-with-sap-api-management-hcp-part-1/
Hi Suman Saha,
how would you establish Principal Propagation to SAP On-Premise environments in cases where you don't want to use a technical user for the Back-End while switching the authentication method?
Instead, the IFlow is called by a third-party application on behald of an individual user.
This is great to connect to Target Endpoint with Basic Auth. However, I have a use case that my Target EndPoint requires OAUTH2 authentication (using a Bearer token). How do I setup policy to get OAtth token from the Target token URL and then pass it as Bearer token to Target EndPoint.