Technical Articles
OAuth2SAMLBearerAssertion Flow with the SAP BTP Destination Service. S/4HANA Cloud.
![]() |
![]() |
This instalment belongs to a mini series of blogs on OAuth2SAMLBearerAssertion Flow leveraging SAP BTP Destination Service with S/4HANA Cloud inbound ODATA services. Bon voyage:) |
Set Up Authentication for SAP S/4HANA Cloud Extensions
There is ample and relatively accurate official documentation on how to configure S/4HANA Cloud for Side by Side or In-App integration with the APIs. And when it comes to inbound communication (e.g. you are calling into S4HC APIs) the end to end user SSO is not only essential but paramount. And precisely, OAuth2SAMLBearerAssertion authorisation flow allows for propagation of a user’s identity from any client application deployed anywhere all the way through to an ODATA-based asset management service (like SAP S/4HANA Cloud in this instance). A truly end to end Single Sign On! |
Putting it all together
As a baseline we will use the following User Propagation Scenario: User Propagation from the Cloud Foundry Environment to SAP S/4HANA Cloud. This scenario is applicable to any brief including with the client application deployed as Other runtime (== other than SAP BTP CF or Kyma runtimes). Good to know:
|
Configure OAuth communication with S/4HANA Cloud.
We will follow the sequence of the configuration tasks as described in the official documentation, namely:
Configuration TasksPerform these steps to set up user propagation between S/4HANA Cloud and the SAP BTP Cloud Foundry environment. Tasks
Also Set Up Authentication for SAP S/4HANA Cloud Extensions is very relevant piece of documentation. |
Quovadis-S4HC.
Assuming you have the right level of access to your target S4HC system and that you have created a communication user you may now create there your own OAuth2.0 client application (=communication system+communication arrangement).
Let’s call it Quovadis-S4HC.
Configure the OAuth2.0 Identity Provider in the Communication System.
One piece of information you will need from the Destination service created on SAP BTP sub-account level is the trust’s public x509 certificate that you will need to insert into the Quovadis-S4HC OAuth2.0 Communication System as depicted below:
A fairly common question. What is the Provider Name? The provider name designated the issuer of the saml bearer assertion. The provider name defaults to the Issuer’s x.509 certificate CN (Common Name). When uploading the destination service signing certificate, the CN will be populated automatically to both the Signing Certificate Subject and Issuer sections to the left . Make sure you copy the CN field and assign it as a Provider Name (as it will not be populated). Good to know:
|
Last but not least you can create a communication arrangement for a given communication scenario.
Create a communication arrangement for a given communication scenario.
Creating a communication arrangement (that uses this communication system) will result in creating of an OAuth2.0 client with the client_id and client_secret equal the communication user name and password respectively. The SAML2 Audience is the service provider and is the value of your S4HC tenant URL. The Token service URL is the OAuth2.0 IdP endpoint. The Destination service will call this endpoint with the saml assertion it has generated internally. You can add the required scope as a Token service URL endpoint's query parameter (?scope=<scope>) or you can pass it in the scope property in the destination definition. You will need the above OAuth2.0 client details when creating a destination definition below. |
Creating a destination.
Create a Destination service instance on a BTP sub-account level (that can be done with a trial BTP account as well)
Before you can configure the API hub sandbox environment you will need to have created an instance of the destination service. Choose Other as the runtime environment and give the service instance a name, for instance Quovadis Next configure your API Business Hub sandbox with the above destination service credentials. Please refer to the following article on the details for the sandbox environment configuration with SAP API Business Hub. |
You can create a destination definition using either GUI of the SAP BTP sub-account or programmatically calling the destination service APIs.
Assuming you will be rehearsing the access to the destination
service APIs with the SAP Business API Hub sandbox environment
or alternatively using the API Management,
you do not need to write a single line of code.
All you need to do is create a definition of your destination
as demonstrated below.
Then you may call that destination with the destination
service find api any time you need to procure a bearer access token
to authorize access to remote S4HC resource.
Most of the values in the below destination definition will need to come from the OAUTH2.0 service – the so called Communication Arrangement – from S4HC tenant. |
Create destination definition programmatically with API.You could grab the below json structure, enter your values and use it with the destination service POST/PUT destinations APIs |
Post (=create) a new destination:
Put (=update) an existing destination:
https://destination-configuration.cfapps.xx99.hana.ondemand.com/destination-configuration/v1/subaccountDestinations
{
"Name": "Quovadis-S4HC",
"Type": "HTTP",
"URL": "https://my999999.s4hana.ondemand.com/sap/opu/odata/sap/API_PURCHASEORDER_PROCESS_SRV",
"Authentication": "OAuth2SAMLBearerAssertion",
"ProxyType": "Internet",
"tokenServiceURLType": "Dedicated",
"audience": "https://my999999.s4hana.ondemand.com",
"authnContextClassRef": "urn:oasis:names:tc:SAML:2.0:ac:classes:x509",
"Description": "https://api.sap.com/api/API_PURCHASEORDER_PROCESS_SRV/overview",
"clientKey": "<client_id>", //==communication user name
"nameIdFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
"scope": "API_PURCHASEORDER_PROCESS_SRV_0001",
"x_user_token.jwks_uri": "https://<identityzone>.authentication.xx99.hana.ondemand.com/token_keys",
"tokenServiceUser": "<client_id>", //==communication user name
"tokenServiceURL": "https://my999999-api.s4hana.ondemand.com/sap/bc/sec/oauth2/token",
"userIdSource": "email",
"tokenServicePassword": "<client_secret>" //==communication user password
}
Asserting user’s identity
A user’s identity.That’s the most important part of the setup.
You have a choice between a static technical user, or a dynamic user.
The destination service supports dynamic user indentities via
a user JWT token.
You may need to provide an access url to OpenID Connect provider metadata.
Please add in the destination service's x_user_token.jwks_uri property
the value of the jwks_uri url from the OIDC provider metadata.
As aforementionned, the value of this property must come
from the OIDC user identity provider metadata.
In case you are using the XSUAA service as the OIDC provider you could call
the .well-known/openid-configuration endpoint of the XSUAA service url,
in order to retrieve the OIDC metadata, for instance:
https://<identityzone>.authentication.xx99.hana.ondemand.com/.well-known/openid-configuration
then you will look for jwks_uri and copy the value of jwks_uri
(it is yet another url) to the x_user_token.jwks_uri property
in the destination defintion.
Disclaimer:
In a productive scenario you must be using a user JWT token!
However a technical user may be used in the initial sandboxing
and concept proving of the entire configuration.
In either case, the user must exist in both the client application
and the target S4HC system.
Finding destination.Obtaining the bearer access token to call into S4HC business API.
Find destination API call:
https://destination-configuration.cfapps.xx99.hana.ondemand.com/
destination-configuration/v1/destinations/Quovadis-S4HC
Please substitute xx99 by the BTP subaccount region where you
have provisionned the destination service on a subaccount level,
for instance 'eu10' etc.
As a result of this call you will get the bearer access token that you can use to call into S4HC OData API, and retrieve the assets like Purchaser Orders or Sales Orders, your user has been granted access to, for instance:
"authTokens": [
{
"type": "Bearer",
"value": "-hY-nuoXHtusskpbJBHeC4EX8jPi0jYZ7RAZP9Q7_WadI111",
"http_header": {
"key": "Authorization",
"value": "Bearer -hY-nuoXHtusskpbJBHeC4EX8jPi0jYZ7RAZP9Q7_WadI111"
},
"expires_in": "3600",
"scope": "API_PURCHASEORDER_PROCESS_SRV_0001"
}
]
Conclusion.
Last but not least. Let’s see the rationale behind using the Destination Service.
|
__________
Additional resources.
Hello Piotr
I have some queries
Please suggest
Hello Abhijit,
Thanks for taking time and reading through the blog.
Back to your questions.
To reiterate: The authentication scenario described in this blog is OAuth 2.0 SAML Bearer Assertion (inbound connections).
Why? because it allows for a truly end to end user Single Sign On.
And this is why I am not dealing with the Basic Authentication for inbound communication in this blog.
I would refer you to the chapter 5 of this excellent S/4HANA Cloud handbook on extensibility topics
Set Up Authentication for SAP S/4HANA Cloud Extensions
ad 1.
Please refer to the Asserting user’s identity above.
In a nutshell, with the OAuth2SAMLBearerAssertion authentication brokered by SAP BTP Destination service you will need to provide a user JWT token as a client application user's identity proof.
In a typical integration scenario with SAP BTP sub-account as a service provider, the BTP XSUAA service would be the OIDC provider. Moreover, if the client application is deployed on BTP CF then the user's JWT Token would be passed directly to that application by the XSUAA.
However, any OIDC provider would do (including IAS if configured as OIDC provider for user authentication against your application). But you might need to transport the user's JWT token to find destination API manually via the X-user-token header.
This is all described in very detail in the destination service documentation.
For instance quoting after: https://api.sap.com/api/SAP_CP_CF_Connectivity_Destination/resource
The X-user-token header is only taken into account for authentication type that require user information to be provided (such as OAuth2UserTokenExchange, OAuth2JWTBearer, SAPAssertionSSO (deprecated!) and OAuth2SAMLBearerAssertion).
If provided, the value must be a user JWT token in encoded form (see https://tools.ietf.org/html/rfc7519).
If provided, it will be used with priority over the Authorization header for the token exchange operation. This means that the user token from this header will be used when determining the user and the tenant subdomain and will also be the token, for which token exchange is performed. If this header is not provided, the user token from the Authorization header will be used
ad 2.
S/4HANA Cloud has 200+ ODATA APIs. Which API(s) you have in mind ? Otherwise it is a simple check on api.sap.com
ad 3.
IP Address Restriction is more of a networking craft.
I'm afraid I cannot be of much help here.
Please have a look a the following community thread on this topic
kind regards
Piotr
Hello Piotr,
->we are trying to access the OData APIs using Oauth as an authentication method.

Communication System:
->we have followed your blog and are trying to use destination API(Cloud foundry) to call access token for the required scope.
->we are not going to deploy any app on BTP.
->Business user is set in both identity tenant and s4hanacloud (Business user email: neha.bagalkot@bcone.com)
->we have configured HTTP destination as follows
Destination Service Key:
( We have sent it in the same email trail in the reply)
->calling destination service is giving us the following error:
"authtokens": [
{
"type": "",
"value": "",
"error": "org.apache.http.HttpException: Request to the /userinfo endpoint ended with status code 403",
"expires_in": "0"
}
]
->some areas of confusion
-where should we pass this business user email so that nameid can use it?
-what should be the hostname and logical system in s4hanacloud?
-do we need to use the JWT token? if yes how can we obtain one without binding any app to xsuaa.
->we have tried setting nameidformat as unspecified but then we got the following error
"authTokens": [
{
"type":
"value" :
"error": "Retrieving of OAuthToken failed due to the following reason: Cannot determine the user to propagate for o
Auth2SAMLBearerAssertion destination. Either provide user_token JWT token (https://docs.cloudfoundry.org/api/uaa/vers
ion/4.7.1/index.html#user-token-grant) when retrieving the destination or configure it with Systemuser.",
"expires_in": "0"
}
]
}
->we came across a step that was not in the official SAP document please tell us if need to do it.
-download metadata from SAP BTP and provide it to Cloud Identity Tenant to generate trust between BTP and cloud identity Tenant.
Regards
SM
Hello Sidhant Mahajan,
Thanks for reading my blog and your questions.
In order to help you and other readers who may have similar questions I have scrambled a brand new blog that describes how to call into Product Master ODATA APIs with the OAuth2SAMLBearerAssertion flow using the destination service from SAP BTP platform.
Generally speaking, the main idea behind the OAuth2SAMLBearerAssertion flow is to propagate the identity of a resource owner from a client application to a remote target system.
ad 1. You receive a 403 error when calling a destination because you have not provided a resource owner user identity in the destination definition. The simplest way of doing this is to use the SystemUser property.
Please refer to the aforementioned blog for working examples of destinations. Just replace the placeholders in the provided definitions with the values from your S/4HANA Cloud system.
Please also note that SystemUser property can designate either a business user (=with either the email address or a user name) or a technical user of the target system (S/4HANA Cloud in this instance).
But when using SystemUser property there is no need to use the userIdSource property. However, nameIdFormat property is still very relevant and must be set accordingly. Please look up destination definitions from my latest blog.
Please note that only the Product Master (A2X) supports a business user identity. All the remaining ODATAv4 APIs can only support the communication user identity.
Once you are able to generate bearer access tokens for all your use cases and then consume the ODATA API(s) from your client application you can start thinking about ways of replacing the SystemUser.
ad2. Please first try to make your destinations work with the SystemUser property using the definitions templates from my latest blog.
ad3. the hostname and logical system in s4hanacloud communication system are relevant for outbound APIs only. As in this exercise you are trying out the inbound APIs please tick the inbound checkbox. However, if you wanted to implement the outbound interfaces as well please refer to the ample setup instructions included in the business Master Data Integration scenario 1RO
ad4. you may need the user JWT Token as a way of providing the user identity in lieu of the SystemUser property. We can discuss how to do it once your destinations are working fine with the SystemUser.
But in general if you want to avoid using the xsuaa you will need to use another OIDC provider of your choice. Have a read here and there
ad5. same as ad2. Please first try to make your destinations work with the SystemUser property using the definitions templates from my latest blog.
ad6. same as above; Please first try to make your destinations work with the SystemUser property using the definitions templates from my latest blog.
Generally speaking, when deploying applications to BTP, a BTP sub-account is the acting service provider and SAP IAS of your S/4HANA Cloud system is the identity provider. Thus in order to use the S4HC SAP IAS as the identity provider for the business applications deployed on this BTP sub-account a trust needs to be established between the two of them via the exchange of metadata descriptors.
Actually this is very well documented in SAP help pages as this is a common operation.
kind regards; Piotr
Hello Piotr,
Made the necessary changes as per your response but now getting some error regarding the content type.
We have tried with postman also, all of the possible content types in headers but the error is the same as shown below:
Error:
"authTokens": [
{
"type": "",
"value": "",
"error": "Do not support OAuth Service content reponse type: text/html",
"expires_in": "0"
}
]
Regards
SM
Hello Sidhant Mahajan,
All I can suggest that assuming both the destination definition and the S4HC communication arrangement are correctly defined is that you test the destination call-out from API Business Hub.
https://blogs.sap.com/2021/10/07/s-4hana-cloud-product-master-apis-with-oauth2samlbearerassertion/#try-out
best regards; Piotr
Hello Piotr,
We tried calling BTP destination using destination API for client certificate authentication
This is the response::
How do we call any S4Hana Cloud API using client certificate authentication on postman?
Regards
Sidhant
Hello Sidhant Mahajan,
Here is my latest blog post that should help you with your question.
Out of my curiosity you are showing the destination service payload and your ask is about Postman? kind regards;
Piotr
PS. I am noticing you are using different users : https://people.sap.com/chiran9987 or https://people.sap.com/jsrpanky101. What is your relationship with SAP ?