SAP Cloud Integration – OAuth2 Client Credentials Support in OData V2 Adapter
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.
- 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
- 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.
- Grant Type: Select the grant type. Two grant types available
- Client Credentials
- Select Client Credentials grant type for our scenario
- Authentication URL: Provide the URL of OAuth2 token server which shall generate the token and returns it.
- Client ID: Client ID of registered OAuth2 client
- Client Secret: Client Secret of registered OAuth2 client
- 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
- Send as Body Parameter: Sends client ID and secret as request body in JSON format
- Send as Request Header: Sends the client ID and secret as part of the request header
- Scope information: If your OAuth2 token service requires scope to be sent, the select the check box of Include Scope
- Scope: The scope information
- Content Type: One of the two values to be selected
- application/json: In case of scope is in json format
- 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.
Good reference Deepak. Bookmarking it
Thanks for the feedback.
Thanks for the very informative blog. Does the OData adapter support OAuth for inbound messages? Can you share some information on this.
Very nice blog :May i know what Query u gave in Processing Tab in Odata V2 call ? to get the token.
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.
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.
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.
Hi Deepak Govardhanrao Deshpande
How is the required parameter grant_type=client_credentials passed to the token endpoint, do you know?
The parameter is internally added by the respective outbound adapter/connector while making call to OAuth2 token endpoint.
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
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?
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?
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?
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.
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:
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.
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.
We may be reading something different, this is what I read.
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.
Hi Philippe Addor,
Yes, Morten Nielsen is in fact correct ! Sorry, my mistake.
I hope inputs from Ivan Mirisola and Morten Nielsen helps here.
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?
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
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 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 🙂
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!
Yes, OAuth2 client credentials token caching is implemented for OData v2/v4 and HTTP receiver adapters.
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 ?
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.
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!
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.
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,
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 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?
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 for the clarification and quick response.
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 :
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 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?
SAP Cloud Integration doesn't support password grant out of box unlike client credentials.
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?