Skip to Content
Product Information
Author's profile photo Deepak G Deshpande

SAP Cloud Integration – OAuth2 Client Credentials Support in OData V2 Adapter

Introduction

SAP Cloud Integration version 2.43.x comes with enhancement in OData V2 receiver adapter with support of OAuth2 Client Credentials. If you have an OData V2 endpoint to consume, with OAuth2 Client Credentials grant type authentication, you can invoke it.

This blog describes about the new enhancement.

OAuth2 Client ID and Client Secrete

The consumption of this feature starts with registering a client with OAuth2 token service provider. Since different applications have different way of registering the OAuth2 client, I will not be covering on how to register it. But, the outcome of any OAuth2 client registration process is that you get a client ID and client secrete along with an optional scope information.

OAuth2 Security Artifact Deployment

You need to deploy the OAuth2 security artifact before consuming this information in the OData V2 receiver adapter. Below steps describe on how to deploy OAuth2 security credentials.

  1. In your SAP Cloud Integration Web UI, click on Monitoring -> Manage Security ->Security Materials -> Add -> OAuth2 Credentials. Sample screenshot below

 

This opens the OAuth2 credentials dialog window as below

Parameters information:

  1. Name: Any name of your choice, this is also called as alias, to be used in the Credential Name field of OData V2 receiver adapter.
  2. Grant Type: Select the grant type. Two grant types available
    1. Client Credentials
    2. OAuth2SAMLBearerAssertion
  3. Select Client Credentials grant type for our scenario
  4. Authentication URL: Provide the URL of OAuth2 token server which shall generate the token and returns it.
  5. Client ID: Client ID of registered OAuth2 client
  6. Client Secret: Client Secret of registered OAuth2 client
  7. Client Authentication: Two values available. Based on the way OAuth2 token service requires the client ID and secret to be sent as part of request, select the one relevant
    1. Send as Body Parameter: Sends client ID and secret as request body in JSON format
    2. Send as Request Header: Sends the client ID and secret as part of the request header
  8. Scope information: If your OAuth2 token service requires scope to be sent, the select the check box of Include Scope
    1. Scope: The scope information
    2. Content Type: One of the two values to be selected
      1. application/json: In case of scope is in json format
      2. application/x-www-form-urlencoded: In case of scope is in x-www-form-urlencoded format

Click on Deploy button

 

Design Integration Flow

Steps of complete design of integration flow shall be excluded as the expectation is that you know how to design the integration flow in SAP Cloud Integration already.

Consider the below integration flow with OData V2 receiver adapter.

In the OData V2 receiver adapter, the Authentication drop-down control has a new entry for OAuth2 Client Credentials. Select this option. In the Credential Name field, provide the name, i.e. alias what you have used at the time of deploying the OAuth2 Client Credentials security artifact (cover under the section OAuth2 Security Artifact Deployment). When the message processing starts, the OData V2 runtime adapter reads the alias, gets the client ID and secret, makes an HTTP request call to OAuth2 token service URL – along with scope if provided – and upon receiving the OAuth2 token, OData V2 runtime adapter sets this token to Authorization bearer header and invokes the OData V2 endpoint provided in the Address field.

Assigned Tags

      45 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Sreehari V Pillai
      Sreehari V Pillai

      Good reference Deepak. Bookmarking it

      Author's profile photo Deepak G Deshpande
      Deepak G Deshpande
      Blog Post Author

      Hi Sreehari,

      Thanks for the feedback.

       

      Thanks

      Deepak

      Author's profile photo Muhammad Ahmed
      Muhammad Ahmed

      Hi Deepak

      Thanks for the very informative blog. Does the OData adapter support OAuth for inbound messages? Can you share some information on this.

      Best Regards

      Muhammad Ahmed

       

      Author's profile photo Giuseppe Devito
      Giuseppe Devito

      Hi Deepak,

      Good tutorial

      Giuseppe

       

      Author's profile photo Sriram Nagarajan
      Sriram Nagarajan

      HI Deepak,

      Very nice blog :May i know what Query u gave in Processing Tab in Odata V2 call ? to get the token.

       

      Author's profile photo Deepak G Deshpande
      Deepak G Deshpande
      Blog Post Author

      Hi Sriram,

      The Address field (of OData V2 outbound connector properties) should have the OData V2 service root endpoint. It is not the OAuth2 token service URL.

      OAuth2 token service URL should be part of the credential deployment dialog, and should be part of Authentication URL field of the dialog. And we will correct the UI label from 'Authentication URL' to 'Token Service URL'

      I hope this answers your question.

       

      Thanks

      Deepak

      Author's profile photo Marek Zikmunda
      Marek Zikmunda

      Hi Deepak,

      is there a way to use grant_type or any other key / value in Manage Security Material for OAuth2 credentials? Typically for grant_type values such as  “client_credentials” or “password”, etc. would be really nice to have, as these are usually mandatory for OAuth 2.0.

      So we do not have to follow posts like this : https://blogs.sap.com/2017/01/24/hci-integrating-salesforce-using-hci-using-rest-api/

      thank you in advance for your answer.

      Regards,

      Marek

      Author's profile photo Deepak G Deshpande
      Deepak G Deshpande
      Blog Post Author

      Hi Marek,

      Sorry for the very late reply, somehow I missed your comment.

      Are you looking for a generic key/value pair persistence? For OAuth2 client credentials, I think the current dialog for OAuth2 for deployment of client ID and client secrete would be sufficient.

       

      Thanks

      Deepak

      Author's profile photo Morten Nielsen
      Morten Nielsen

      Hi Deepak Govardhanrao Deshpande

       

      How is the required parameter grant_type=client_credentials passed to the token endpoint, do you know?

      https://tools.ietf.org/html/rfc6749#section-4.4.2

       

      Best Regards

      Morten

      Author's profile photo Deepak G Deshpande
      Deepak G Deshpande
      Blog Post Author

      Hi Morten,

      The parameter is internally added by the respective outbound adapter/connector while making call to OAuth2 token endpoint.

       

      Thanks

      Deepak

      Author's profile photo Morten Nielsen
      Morten Nielsen

      Thanks I would also believe it was.

       

      We have some issues with exactly that, maybe we're doing something wrong, we have a hard time trying to debug it.

       

      I would expect grant_type=client_credentials to be passed in the request body.

      With cUrl it would look like:

      curl -X POST -H "Authorization: Basic [base64 usename:password]" -H "content-type: application/x-www-form-urlencoded" -H "Accept: application/json" -d "grant_type=client_credentials" https://......./oauth2/token

      Author's profile photo Deepak G Deshpande
      Deepak G Deshpande
      Blog Post Author

      Hi Morten,

      Can you change the drop-down (combo-box) value of Client Authentication to Send As Request Header rather than Send as Body Parameter and try it?

       

      Thanks

      Deepak

      Author's profile photo Morten Nielsen
      Morten Nielsen

      Hi Deepak

      We have tried "Send as Request Header", and it still does not work.

      Then also checking "Include Scopes", adding a blank/space as scope value (we do not utilize scopes) - then it seems to work.

      This behavior is rather strange?

      Best Regards

      Morten

      Author's profile photo Laxmi Narasimha Prasad Konda
      Laxmi Narasimha Prasad Konda

      Hi,

      Even I have tried many ways to use the oauth 2(as body,as header, as json, as url) - by declaring in security materials .. However I am not able to get this work. I have noticed the below error in log. , why it is missing the authorization in header if we mention authentication as Oauth2 client credentials?

      I have implemented oauth2 token generation / bearer token inside flow and called my actual url and it worked without issues....

      Seems some limitation / wrong type of execution / configuration is occurring when we consider oauth2 via security material artifact ? Do we have any mock endpoint / interceptor where we can see the headers / data which is being passed to the URL from http channel and can we monitor how the token call is taking place?

      Regards

      Prasad

       

      Author's profile photo Deepak G Deshpande
      Deepak G Deshpande
      Blog Post Author

      Hi Morten,

      Thanks for the update.

      Setting the drop-down entry to Send as Request Header is expected to work.

      I am not able to relate this with selecting include scopes and adding a blank/space as scope value.

      Nevertheless, I am in touch with development team to crosscheck this behaviour and will update you.

       

      Thanks

      Deepak

      Author's profile photo Philippe Addor
      Philippe Addor

      Hi Deepak

      I'm facing the same problem as Morten last year. And the workaround with the space doesn't work (anymore).

      The point is that it's not about the authorization header. You say we should configure the credentials as "Send as Request Header". That doesn't help because it's not about the authorization header (which is correct in my case in the header), but about the query string "grant_type=client_credentials". Our API needs this not in the URL but in the body as a json string like the following:

      { "grant_type" : "client_credentials" }

      It would look like this in Postman:
      There needs to be an option to configure if that should be in query string or in the body!
      Did anybody solve this problem in another way than manually building the Oauth2 flow?
      Thanks,
      Philippe

       

      Author's profile photo Morten Nielsen
      Morten Nielsen

      I'm not sure if this is relevant, but looking at your screenshot the request is wrong.
      The std. says request Content-Type must be application/x-www-form-urlencoded, not raw, and it is passed in the body.

      https://datatracker.ietf.org/doc/html/rfc6749#section-4.4

      Author's profile photo Ivan Mirisola
      Ivan Mirisola

      Hi Philippe Addor,

      According to the RFC https://datatracker.ietf.org/doc/html/rfc6749, the grant_type is supposed to be sent as a URI parameter. If your API is getting this from the body in JSON format, that is not compliant to the RFC. It doesn't mean you shouldn't use it that way or that the API implementation is wrong. It just means you are not using a compliant way of calling an OAuth2 process.

      Since your API isn't compliant with the RFC, then either you change it to be compliant and benefit of the standard integration available in BTP. Or you should manually build the request to the OAuth2 endpoint. I suppose you could achieve this using a Groovy Script.

      Best regards,
      Ivan

      Author's profile photo Morten Nielsen
      Morten Nielsen

      Hi Philippe,

       

      We may be reading something different, this is what I read.

      
      
      Best Regards
      Morten
      
                    
      Author's profile photo Philippe Addor
      Philippe Addor

      Hi Ivan Mirisola

      Thank for your answer. I am with Morten Nielsen in his reply below that the RFC says that the grant type goes into the body of the POST request. However, you seem to be right that the API is not fully comply with the standard since they require the string as JSON. It doesn't work as x-www-form-urlencoded in this case.

      By the way, the API is actually the one at dnb.com. We have no influence onto their implementation.

      I will go with a custom implementation for now.

      Best Regards,

      Philippe

       

      Author's profile photo Ivan Mirisola
      Ivan Mirisola

      Hi Philippe Addor,

      Yes, Morten Nielsen is in fact correct ! Sorry, my mistake.

      Best regards,
      Ivan

      Author's profile photo Deepak G Deshpande
      Deepak G Deshpande
      Blog Post Author

      Hi Philippe,

      I hope inputs from Ivan Mirisola and Morten Nielsen helps here.

       

      Thanks

      Deepak

      Author's profile photo Vijay Devulapalli
      Vijay Devulapalli

      Dear Deepak

      Thanks for responding to the forum!

      Just have a query, lets say a Bearer Token is configured to be valid for 60 minutes, once CPI fetch the token value, can you please suggest if CPI automatically caches the valid token value till 60 mins or each time the iflow is executed, a call is made to token bearer OAUTH API irrespective of 60 mins duration?

      Sample scenario:

      Step 1: Source system sends 10 Records

      Step 2: SAP CPI needs to sends the data to target system by performing a Request Reply call for each record (via OAUTH credentials configured in Request-Reply Channel)

      Step 3: Enrich the content with the source data

      Step 4: Delivery message to target system with 10 enriched records

      Many Thanks!

      Vijay Devulapalli

      Author's profile photo Deepak G Deshpande
      Deepak G Deshpande
      Blog Post Author

      Hi Vijay,

      As of now, OAuth2 token caching is not done.

      But, we are currently working on to support the OAuth2 caching.

      I will update this blog once the token caching mechanism in introduced.

       

      Thanks

      -Deepak

      Author's profile photo Vijay Devulapalli
      Vijay Devulapalli

      Thanks Deepak for your prompt response.

      As caching is the key to avoid the number of API calls within the bearer token time limit, this would really help considering the performance impacts.

      Waiting for the update 🙂

      Thank you!

      Vijay Devulapalli

      Author's profile photo Philippe Addor
      Philippe Addor

      Deepak Govardhanrao Deshpande

      Can you confirm that Oauth token caching is now implemented? I mean independent of the adapter, e.g. in Odata and in HTTP adapter.  Thank you!

      Author's profile photo Deepak G Deshpande
      Deepak G Deshpande
      Blog Post Author

      Hi Philippe,

      Yes, OAuth2 client credentials token caching is implemented for OData v2/v4 and HTTP receiver adapters.

       

      Thanks

      Deepak

      Author's profile photo Chandrakanth Angannagari
      Chandrakanth Angannagari

      hi,

      • is there a document explaining the difference between OAuth vs OAuth2?
      • is OAuth2 now the recommended method for CPI ?
      • Does this also support SOAP Adapter on CPI ? I have seen on other threads that it does not but these threads were 2 years old
      Author's profile photo Deepak G Deshpande
      Deepak G Deshpande
      Blog Post Author

      Hi Chandrakanth,

      • From SAP Cloud Platform Integration perspective, we provide documentation on the product, and for the difference between OAuth and OAuth2, you need to check on the specifications of OAuth online.
      • It depends on your integration scenario from CPI to outbound connectivity. If your backend supports OAuth2, then it is recommended over Basic Authentication.
      • As of now, there is not support for SOAP outbound adapter in CPI. Do you have such a scenario to connect to SOAP backend from CPI with OAuth2 authentication?

       

      Thanks

      Deepak

      Author's profile photo Chandrakanth Angannagari
      Chandrakanth Angannagari

      hi Deepak,  how about HTTPS adapter? is OAUTH2 supported with HTTPS?

      Is there any guideline about when to use OAUTH and when to use OAUTH2 ?

      Author's profile photo Deepak G Deshpande
      Deepak G Deshpande
      Blog Post Author

      Hi Chandrakanth,

      Yes, HTTPS receiver/outbound adapter also supports OAuth2.

      If a backend supports OAuth2, then you need to make use of this authentication in outbound/receiver adapter.

      Thanks

      Deepak

      Author's profile photo Lani Delos Santos
      Lani Delos Santos

      Hi Deepak,

      We followed the steps you provided above but the third party system mentioned that we still have the 401 error because there is no bearer/authorization. Can you please help on what else do we need to setup? Thanks!

      Author's profile photo Deepak G Deshpande
      Deepak G Deshpande
      Blog Post Author

      Hi,

      There is no major setup involved here, and I hope the backed is correctly configured to receive token requests, and sends out the OAuth2 token and then authorizes the tokens as well for the backend resource call. If you still face issues, please raise ticket with relevant details.

       

      Thanks

      Deepak

      Author's profile photo Dinesh M
      Dinesh M

      Hi Deepak,

      Really Good explanation! I got an overview of how Token Authentication works. Just one query

      This method simplifies the Token Generation process but how the generated token will be helpful while connecting to Receiver -1 ? Will there be any reference to the generated token from Previous step here!!? Please clarify

      Thanks in advance,

      Dinesh

      Author's profile photo Deepak G Deshpande
      Deepak G Deshpande
      Blog Post Author

      Hi Dinesh,

      The outbound/receiver adapter (in this case OData V2) would take care of accessing the token first and then using it in calling the actual endpoint. And OData v2 connector caches (with recent updates) the token and re-uses if it is not expired, and it gets cached against the credential name/alias (e.g. OAuth2ClientCred in my above example screenshot, which is the name given while deploying the credentials). So, if this alias is re-used in another connector for same backend, then token gets re-used.

      Hope this clarifies

       

      Thanks

      Deepak

      Author's profile photo Venkateswararao Dasari
      Venkateswararao Dasari

      Hello Deepak,

      thanks for the tutorial. It's very informative.

      I would like to check with you on OAuth2 token caching mechanism. Is this mechanism is introduced now or its still in process by SAP? Please provide an update on this.

      Will the HTTP adapter also work on caching mechanism if we are using the oauth2 credentials in the http adapter configuration?

      Best regards,

      Venkat

      Author's profile photo Deepak G Deshpande
      Deepak G Deshpande
      Blog Post Author

      Hi  Venkat,

      As mentioned in the above response to Dinesh's comment, yes, OAuth2 caching has been enabled in OData V2 and HTTP outbound/receiver adapters.

       

      -Thanks

      Deepak

      Author's profile photo Venkateswararao Dasari
      Venkateswararao Dasari

      Hi Deepak,

       

      Thanks for the clarification and quick response.

       

      Best regards,

      Venkat

      Author's profile photo Anuradha Ganji
      Anuradha Ganji

      Hi Deepak,

      I am very new to this CPI technology , just beginner , I have followed your article and created the flow. But when I deployed the process I got the below error can you please help me out here what would be the issue :

       

      Error Details
      com.google.common.util.concurrent.UncheckedExecutionException: java.lang.IllegalArgumentException: Exception occured while fetching OAuth Token. Reason: ilesbsanity.insurancearticlez.com:443 failed to respond, cause: org.apache.http.NoHttpResponseException: ilesbsanity.insurancearticlez.com:443 failed to respond
      I have created the Credentials and flow as well and referred the credentials in the flow as well but still got the above error.
      Thanks
      Anuradha.
      Author's profile photo Deepak G Deshpande
      Deepak G Deshpande
      Blog Post Author

      Hi Anuradha,

      Are you still facing the issue? If so, request you to contact your tenant administrator to get a ticket component and raise a ticket.

       

      Thanks

      Deepak

      Author's profile photo Ana Caorsi
      Ana Caorsi

      Hi Deepak.

      Thanks for this blog, is was very helpful.

      In our case when we do the POST to get the token in Postman, we need to pass other parameters as username and password, also grant_type = password. Will CPI support that in the SCOPE area of the Security Material created?

      Thanks!

      Ana

      Author's profile photo Deepak G Deshpande
      Deepak G Deshpande
      Blog Post Author

      Hi Ana,

      SAP Cloud Integration doesn't support password grant out of box unlike client credentials.

       

      Thanks

      Deepak

      Author's profile photo Daniel Weinberg
      Daniel Weinberg

      Hi Deepak,

      we need to use OAuth2 in combination with an end point made available via the SAP Cloud Connector. It seems not to be supported as I keep getting an UnknownHostException. Do you know if there is a chance to get that scenario running?

      Regards,

      Daniel

      Author's profile photo Camille Laroche
      Camille Laroche

      Hello

      i get exactly same question, the token url, which is the url of our sap backend onPremise (so internal address) can not be reach from Cloud Integration (which is in Internet). Is there any way to use the "cloud connector" (as for the HTTP adapter in the iflow) ?

       

      Thanks

      Author's profile photo Daniel Weinberg
      Daniel Weinberg

      Hi Camille,

      Unfortunately, I was not able to make it run.

      Regards,

      Daniel