Skip to Content
Technical Articles

CSRF token validation failed – Post to oData Service via Communication scenario

Problem Statement:

Many a times while using a communication scenario, we face an issue while triggering a post call to the service, with third party api/clients.

Since CSRF tokens are involved, first call is needed with GET to the service with x-csrf-token value as fetch. Response return as token and then this token is used to make a POST call to the server for the oData service

Solution:

There can be many reasons for the same, one most usual and common reason is using the separate http client for GET and POST of the call.

As new instance for the HTTP Client will have separate session and the token validation will be failed in that case.

Let us consider an example.

oData Service: API_CV_ATTACHMENT_SRV

Communication Scenario: Product Lifecycle Management – Master Data Integration (SAP_COM_0105)

The above service and scenario is externally used to make attachments to S/4HANA systems. This needs to have following header parameters to make a post call to create an attachment. Entity set to be used is: AttachmentContent

Header Params:

SLUG, Authorization, BusinessObjectTypeName, LinkedSAPObjectKey, X-csrf-token

For other header parameters you can refer the API document from API hub, Here i will focus more on x-csrf-token.

 

Now for ref, i am using an HttpClient from org.apache.http

The POST to the service is done in two parts:

  1. GET request to the service with header token: x-csrf-token and value as fetch. As a response, we will get the token value as a header parameter. Authorization is also needed for which communication user can be used.
  2. POST request to the service using the same token(x-csrf-token) with key value.

Now refer the below snippet:

final HttpGet get = new HttpGet("https://{host}:{port}/sap/opu/odata/sap/API_CV_ATTACHMENT_SRV");
get.setHeader("X-CSRF-Token", "fetch");
get.setHeader ("Authorization", basicAuth);
final CloseableHttpAsyncClient httpClient = HttpAsyncClients.createDefault();
httpClient.start();

This will trigger the request to fetch the token.

 

Future<HttpResponse> responseGet  = httpClient.execute(get, new FutureCallback<HttpResponse>() {
				  public void completed(final HttpResponse response2) {
			            
			            System.out.println(get.getRequestLine() + "->" + response2.getStatusLine());
			            Header[] header = response2.getHeaders("X-CSRF-Token");
						  System.out.println(header[0].getValue().toString());
						  
						  final HttpPost post = new HttpPost("https://{host}:{port}/sap/opu/odata/sap/API_CV_ATTACHMENT_SRV/AttachmentContentSet");
						  post.addHeader("Content-Type", MimeType);
post.addHeader("LinkedSAPObjectKey","AUT000000000000001000000423700000");
						  post.addHeader("BusinessObjectTypeName","DRAW");
						  post.addHeader("slug",Slug);
						  post.addHeader ("Authorization", basicAuth);
						  post.addHeader ("X-CSRF-Token", header[0].getValue());
ByteArrayOutputStream result = new ByteArrayOutputStream();
							byte[] buffer = new byte[1024*1000];
							int length;
							
								while ((length = is.read(buffer)) != -1) {
								    result.write(buffer, 0, length);
								}
							result.toString("UTF-8");
StringEntity content;
							
								content = new StringEntity(result.toString("UTF-8"));
								post.setEntity(content);
Future<HttpResponse> response = httpClient.execute(post, new FutureCallback<HttpResponse>() {
public void completed(final HttpResponse response2) {
// do success task
}
							});
							
						   
			        }
							

Now the above code will push is(InputStream) to the system using API_CV_ATTACHMENT_SRV successfully as it is sharing the same httpClient.

Using the above way, one can overcome the issues w.r.t token validations and also can see how attachments can be posted to S/4HANA system via communication scenario.

 

Be the first to leave a comment
You must be Logged on to comment or reply to a post.