Introduction:
Welcome to my first blog!
While working on an S/4 HANA implementation project we got a requirement to Create IDocs that have very sensitive information like Bank details, Payment details in the S/4 HANA On-Premise system via SAP API Management OAuth 2.0 Authorization Mechanism. Additionally to add an extra security measure we have implemented an access restriction policy in SAP API Management to check if the request is really coming from SAP CPI. This blog post explains how to secure an IDoc API using SAP API Management.
Use Case:
In the Enterprise landscape, it's very important to have secure communication especially if the communication is happening from Cloud to On-Premise. We need to consider that not only communication channel is secure, but also we need to make sure that the API that is called from the cloud is having right security mechanism in place. Recently in one of our customer project, we have received a use case where the customer wanted to filter the client IP addresses for all the On-Premise API (e.g ODATA, IDoc, SOAP) call. Below is the architecture for such kinds of use cases.
In this blog. I will explain two kinds of security policies that are mostly used to secure API.
- How to implement OAuth 2.0 Authentication policies for APIs.
- How to allow access to the APIs with whitelisted IP Addresses.
- How to Configure SAP API Management to create an IDoc in S/4 HANA using SAP CPI.
Prerequisites:
- Set up Integration Suite. This is necessary to create an Integration flow in CPI and Configure SAP API Management. Please follow the step-by-step process in this Link.
- S/4 HANA on-premise system details and Cloud Connector set up to create an IDoc.
Step-by-Step Process:
Create Token Endpoint API:
- In this step we will create the token endpoint in order to generate the access token. Go to API Portal -> Develop -> API -> Create. Provide a dummy URL, API Name, Title and API Base Path.
- Add a “Resource” as “GenerateToken”. We will call this endpoint when we need to generate a token. Keep only “POST” operation because we will be sending the credentials as x-www-form-urlencoded body to the endpoint.
- Now open the policy editor and add an “OAuthV2” policy in the “GenerateToken” flow. In policy snippet window provide the below policy and deploy the API.
<OAuthV2 async="false" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt">
<Operation>GenerateAccessToken</Operation>
<GenerateResponse/>
<SupportedGrantTypes>
<GrantType>client_credentials</GrantType>
</SupportedGrantTypes>
</OAuthV2>
Configure S/4 HANA in SAP API Management:
- At first, we will create an API Provider. Go to API Portal -> Configure -> API Provider -> Create.
- In this step, we will create Key-Value Map with the UserID and Password of S/4 HANA system. which will be required later. Go to API Portal -> Configure -> Key Value Maps -> Create.
- Now create an API Proxy URL. Go to API Portal -> Develop -> APIs -> Create. Select the API Provider created in step 1.
Add Policies to S/4HANA API Proxy:
Here we will set up the policies to connect with S4HANA.
- Here we would apply the Access control security policy from SAP API Management to restrict access of the API only to SAP CPI Client IP ranges. Click on the Policies button in the newly created API proxy for S4HANA.
- Click on the Edit button from the Policy designer, select PreFlow from the ProxyEndPoint and then click on the + button next to the Access Control Policy available under the Traffic Management Policies segment. In policy snippet window provide the sample policy provided below. Note: In the below code only sample IP addresses are mentioned. To restrict other Application without CPI Add all the IPs of CPI cloud foundry mentioned in the Link.
<AccessControl async='true' continueOnError='false' enabled='true' xmlns='http://www.sap.com/apimgmt'>
<IPRules noRuleMatchAction='DENY'>
<MatchRule action="ALLOW">
<SourceAddress mask="24">10.20.30.40</SourceAddress>
</MatchRule>
<MatchRule action="ALLOW">
<SourceAddress mask="24">20.30.40.50</SourceAddress>
</MatchRule>
</IPRules>
</AccessControl>
- The next step is to verify the OAuth token generated from the previous API. Add the OAuth v2.0 verification policy available under Security Policies to our ProxyEndpoint PreFlow step. In policy snippet window provide the sample policy provided below.
<OAuthV2 async="false" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt">
<!-- this flag has to be set when you want to work with third-party access tokens -->
<ExternalAuthorization>false</ExternalAuthorization>
<!-- valid values are GenerateAccessToken, GenerateAccessTokenImplicitGrant, GenerateAuthorizationCode ,
RefreshAccessToken , VerifyAccessToken , InvalidateToken , ValidateToken -->
<Operation>VerifyAccessToken</Operation>
<GenerateResponse enabled="true"/><SupportedGrantTypes/>
<Tokens/>
</OAuthV2>
- As we need to use basic authentication step to create the IDoc in later step, here we will remove the Authorization header. Select PostFlow step from the ProxyEndpoint and then click on the + button Add Assign Message available under Mediation Policies to our API Proxy. In policy snippet window provide the sample policy provided below.
<!-- 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>
- We have already created the key value Map with the username and password of S4HANA system, To Access that in the Policy Select PreFlow step from the TargetEndpoint and then click on the + button Add Key Value Map Operations available under Mediation Policies to our API Proxy. In policy snippet window provide the sample policy provided below. Note: Put the Key Value Map name created in the previous step in the mapIdentifier.
<KeyValueMapOperations mapIdentifier="IdocCred" async="true" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt">
<Get assignTo="private.username">
<Key>
<Parameter>TestUser</Parameter>
</Key>
</Get>
<Get assignTo="private.password">
<Key>
<Parameter>TestPwd</Parameter>
</Key>
</Get>
</KeyValueMapOperations>
- In the next step add the Content Type header in the policy. In the Policy Select PreFlow step from the TargetEndpoint and then click on the + button Add Assign Message available under Mediation Policies to our API Proxy. In policy snippet window provide the sample policy provided below.
<AssignMessage async="false" continueOnError="false" enabled="true" xmlns='http://www.sap.com/apimgmt'>
<Add>
<Headers>
<Header name="content-type">text/xml</Header>
</Headers>
</Add>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>
- In the next step, we have added basic authentication policy to create an IDOC in S4HANA On-Premise system. Select PreFlow step from the TargetEndpoint and then click on the + button Add Basic Authentication available under Security Policies to our API Proxy. In policy snippet window provide the sample policy provided below.
<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>
- Finally the Policy Editor will look like below. ProxyEndpoint PreFlow:ProxyEndpoint PostFLow:TargetEndpoint PreFlow:
Create Application and Product:
- Create Product for both the API. Go to API Portal -> Develop -> Products -> Create. Provide the Name and Title for each product and add the API created in the previous steps. Now publish both the Products.
- Now Create an Application for the Products published in the previous step. Go to API Portal -> Navigation Links -> API Business Hub Enterprise.
- Go to API Business Hub Enterprise -> My Workspace -> + button (Create Application). Add both the Products created in step 1.
- Once the Application is created successfully, we will get Application Key and Application Secret which will be required to create the IDOC. Note: To create an application AuthGroup.API.ApplicationDeveloper is required to have it in the BTP Cockpit Role collection.
If you face "unable to create Application" error while creating an Application, please follow the below steps.
In the BTP Cockpit :-
– Delete the role collection AuthGroup.API.ApplicationDeveloper for your user id.
In the API Business Hub Enterprise : -
– Go to Manage -> Registered Users -> Add your user id.
– Logout of the Developer Portal.
– Log back in and we will see a Register button at the top.
– Click on Register and the user id will get registered.
– Logout of the BTP cockpit which is logged in already.
– Log back in the BTP cockpit and you can see that Role Collection AuthGroup.API.ApplicationDeveloper is automatically assigned to the user id. Now try to create the application.
Create IDoc using SAP CPI:
- Create an OAuth2 Client Credential in CPI. Go to CPI Tenant -> Monitor -> Manage Security Material -> Create -> OAuth2 Client Credential.
- Create a simple Iflow to send an IDoc to the S/4HANA API Proxy endpoint.
- Set Content Modifier body in the below format.
- Configure the HTTP Adapter as below. Now Save and deploy the Iflow.
Test using Postman:
- To generate the OAuth Token using POSTMAN create a new request in POSTMAN and then select the “POST” method. Here the body is being sent as x-www-form-urlencoded in POSTMAN, Set its settings as follows:
– Method: POST
– URL: OAuthService Token URL
– Body:
client_id: set it to the Application key generated while creating the Application.
client_secret: set it to the Application secret generated while creating the Application.
grant_type: "client_credentials".
- To create IDoc in S/4 HANA using POSTMAN remove step 1 in Add Policies to S/4HANA API Proxy section of this Blog. As the Access Control policy will restrict all the IP addresses other than CPI to access the API Proxy.
Once It is removed create a new request in POSTMAN. Select Authorization as OAuth 2.0 and set the setting as below.
Conclusion:
So with the Access control and OAuth 2.0 Authentication policies of SAP API Management we have secured the On-Premise API.
That's it for today. I hope you have enjoyed the blog. Let me know your feedback in the comments section also let me know what are the policies you have implemented in your customer project.
References:
- https://blogs.sap.com/2016/11/14/oauth-with-sap-api-management-hcp-part-1/
- https://blogs.sap.com/2017/08/07/restrict-access-to-api-based-on-ip-addresses/
- https://blogs.sap.com/2020/06/22/part-1-enable-sap-cloud-platform-api-management-in-cloud-foundry-en...