Skip to Content
1
Aug 17, 2015 at 09:25 PM

usage of CSRF token in ABAP report for POST request

3432 Views

Question 1:

I have problems while using REST POST operations in ABAP report in context of the CSRF token

Background: Testing the possibilities of consuming oData services with ABAP reports and handling JSON content

Problem: I always get :

Satus: 403

Response: CSRF token validation failed finisdh

Example ABAP report:

1) first GET to fetch the token

2) make the post with HEADER parameter fetched token X-CSRF-Token

PARAMETERS: partner TYPE but000-partner,

invoice TYPE vbrk-vbeln.

START-OF-SELECTION.

TRY.

DATA: lv_service_url TYPE string,

lo_http_client TYPE REF TO if_http_client,

lo_rest_client TYPE REF TO cl_rest_http_client,

lo_response TYPE REF TO if_rest_entity,

lv_http_status TYPE i,

lv_token TYPE string.

* (1)

** GET CSRF token

cl_http_client=>create_by_url(

EXPORTING url = lv_service_url " oData service URL

IMPORTING client = lo_http_client

EXCEPTIONS OTHERS = 1 ).

CHECK sy-subrc EQ 0.

lo_http_client->request->set_content_type( 'application/json' ).

CREATE OBJECT lo_rest_client EXPORTING io_http_client = lo_http_client.

* fetching token

lo_rest_client->if_rest_client~set_request_header( EXPORTING iv_name = 'X-CSRF-Token' iv_value = 'Fetch' ).

lo_rest_client->if_rest_client~get( EXCEPTIONS OTHERS = 1 ).

CHECK sy-subrc EQ 0.

lo_response = lo_rest_client->if_rest_client~get_response_entity( ).

lv_http_status = lo_response->get_header_field( '~status_code' ).

CHECK lv_http_status EQ '200'.

" get token for POST request

lv_token = lo_response->get_header_field( 'X-CSRF-Token' ).

FREE: lo_http_client, lo_rest_client.

* (2)

** POST with CSRF token

DATA LO_REQUEST TYPE REF TO if_rest_entity.

cl_http_client=>create_by_url(

EXPORTING url = lv_service_url " oData service URL

IMPORTING client = lo_http_client

EXCEPTIONS OTHERS = 1 ).

CHECK sy-subrc EQ 0.

lo_http_client->request->set_content_type( 'application/json' ).

CREATE OBJECT lo_rest_client EXPORTING io_http_client = lo_http_client.

* build Example request data to send

DATA lv_json_post_data TYPE string.

lv_json_post_data = | \{ | &&

| "user":"{ sy-uname }", | &&

| "partner":"{ partner }", | &&

| "invoice":"{ invoice }" | &&

| \} |.

lo_request = lo_rest_client->if_rest_client~create_request_entity( ).

CHECK lo_request IS BOUND.

lo_request->set_header_field( iv_name = 'X-CSRF-Token' iv_value = lv_token ).

lo_request->set_content_type( iv_media_type = if_rest_media_type=>gc_appl_json ).

lo_request->set_string_data( lv_json_post_data ).

* POST

lo_rest_client->if_rest_resource~post( lo_request ).

* Collect response

lo_response = lo_rest_client->if_rest_client~get_response_entity( ).

lv_http_status = lo_response->get_header_field( '~status_code' ).

DATA lv_response TYPE string.

lv_response = lo_response->get_string_data( ).

CASE lv_http_status.

WHEN '201'.

* JSON to ABAP

DATA lr_json_deserializer TYPE REF TO cl_trex_json_deserializer.

CREATE OBJECT lr_json_deserializer.

DATA ls_test_content TYPE ztestrest.

lr_json_deserializer->deserialize( EXPORTING json = lv_response IMPORTING abap = ls_test_content ).

WRITE: /'CreadedBacklinkID:', ls_test_content-hashid.

WHEN OTHERS.

WRITE :/ 'Satus:', lv_http_status.

WRITE :/ 'Response:', lv_response.

ENDCASE.

CATCH cx_root.

ENDTRY.

It works without problems when I deactivate the CSRF token in the SICF for this service with parameter ~CHECK_CSRF_TOKEN = 0

When I deactivating the CSRF token there is the need to use the header parameter X-Requested-With :

lo_request->set_header_field( iv_name = 'X-Requested-With' iv_value = 'X' ).


and it also works in a browser REST test client. Problems are only visible when using the ABAP oo rest client

Question 2 :

The other problem, when the service works the response from the Gateway is XML per default and I have no clue how to say that I also want the returning entity in the server response also in JSON.

Can anyone help me here ?

Thanks in advance,

Thomas