Skip to Content

Archived discussions are read-only. Learn more about SAP Q&A

usage of CSRF token in ABAP report for POST request

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

Tags:
replied

Hello Thomas,

For Question 2,

Try adding an Header -> Accept : application/json


We add this header to get the response of POST operations in json format.


Try and check once.


Regards,

Ashwin

1 View this answer in context

Helpful Answer

by
Not what you were looking for? View more on this topic or Ask a question