No need for CSRF token when calling C4C OData
Real projects requirements and one discussion Webhooks & SAP Cloud application studio which caught my attention recently brought the idea of this blog post.
We know that SAP Cloud for Customer OData API is protected by CSRF token. It’s done to prevent Cross-site request forgery attacks. Which makes sense if we use OData within our user interface.
However, sometimes there is a requirement to integrate an external application to SAP C4C system without CSRF protection. For example, there are webhook scenarios. Or any other application-to-application scenarios you could think of which would use OData as an API. In these scenarios, many 3rd party systems usually do not support any CSRF-related additional calls. At best, they would support basic authentication.
Certainly, we could use some middleware (SAP CPI, SAP API Management or any other decent one), put it in between and perform conversion of the webhook call into a required sequence: fetch (if required) CSRF token and then POST the webhook data (transformed or not) to the OData endpoint of C4C. Frankly speaking, middleware is not required here after all.
One day I’ve been hinted by my colleague Anil Chacko that during his tests he found out something interesting.
Not all OData ‘modification’ calls (POST, PUT, DELETE) require a presence of CSRF-token. And indeed, there is even a note in the official documentation :
When a regular business user is used to access C4C OData API the system asks us to present CSRF token.
Instead, we can use a communication scenario called ‘OData Services for Business Objects’. The user created for this communication system is called ‘integration (technical) user’ in the standard documentation. Let’s quickly check if there is any difference to the well-known approach with the business user.
To start with it, we need a communication system (I named it TECHODATA). And then create a communication arrangement using the created communication system and mentioned communication scenario. In the communication arrangement, we have a communication user created (in my case, it is _TECHODATA). Don’t forget to set a password for it. Next, we need to select services to be included in the communication arrangement. We can change what is included any time later if required. Moreover, it allows to include not only standard services but also custom services. This allows us to define either completely custom services based on custom objects. Or custom services based on standard objects. Remember, that oData Editor in C4C has several nice features which might be helpful. Such as renaming fields or entity types of the exposed service and setting default values for fields.
After we save and activate the communication arrangement, let’s see how the call goes on.
Just a note here: to do a clean test, I’m clearing all cookies before any calls I’m making.
The result is:
Business User approach requires a CSRF token, immediately gives 403 status code back.
Technical user approach requires no CSRF token and happily creates an object announcing the success with 201 status code.
Now we can happily perform webhook calls integration or any other application-to-application integration into C4C without caring about CSRF token much.
Worth noting, that I can access standard OData API endpoint (/sap/c4c/odata/v1/c4codataapi/ServiceRequestCollection) with the technical user. Even though I should have been using the endpoint from my communication arrangement (which is /sap/c4c/odata/v1/ticket/ServiceRequestCollection).
Hope this finds you well!
How do we call this from SDK, would it require CSRF there?
No matter where you're calling it from, the described approach doesn't require CSRF token.
thanks for the post.
But how do I call your example from PDI, since I have to definde scenario and service for the rest call as stated in https://blogs.sap.com/2018/12/06/use-restful-service-to-consume-s4-functionality-in-sap-cloud-for-customer/
Since we don't have a base64 encoder in PDI we cannot add the credentials in the script logic, which further is a security issue.
Not sure why would you need to do any base64 encodings or add credentials in the scripting. From PDI you call a service with communication arrangement defined. In the communication arrangement you store credentials. Not in PDI.