on 08-23-2018 12:55 PM
Hello Experts,
I am triggering a SCP workflow from ABAP system. Below is my code. I am able to get the CSRF token value successfully. But the actual instance creation is not happening I am getting 403 Forbidden error
Note: i am able trigger the instance using postman. so the workflow itself is working fine.
this is my code
*&---------------------------------------------------------------------*
*& Report Z_TRIGGER_SCP_WORFKLOW
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT Z_TRIGGER_SCP_WORFKLOW.
DATA: lo_http_client TYPE REF TO if_http_client.
DATA: response TYPE string.
"create HTTP client by url
"API endpoint for API sandbox
CALL METHOD cl_http_client=>create_by_url
EXPORTING
url = 'https://bpmworkflowruntimeXXXXXea-XXXXX.hana.ondemand.com/workflow-service/rest/v1/xsrf-token'
IMPORTING
client = lo_http_client
EXCEPTIONS
argument_not_found = 1
plugin_not_active = 2
internal_error = 3
OTHERS = 4.
IF sy-subrc <> 0.
"error handling
ENDIF.
"setting request method
lo_http_client->request->set_method('GET').
"adding headers
lo_http_client->request->set_header_field( name = 'X-CSRF-Token' value = 'Fetch' ).
lo_http_client->request->set_header_field( name = 'Content-Type' value = 'application/json' ).
lo_http_client->request->set_header_field( name = 'Accept' value = 'application/json' ).
lo_http_client->request->set_header_field( name = 'Authorization' value = 'Basic XXXXXXXXXXXXXXXXXXXXX' ).
"API Key for API Sandbox
*lo_http_client->request->set_header_field( name = 'APIKey' value = 'Vw0jBxyASfBvXXXXXXXFbEpcTKxizWKr' ).
"Available Security Schemes for productive API Endpoints
"Basic Authentication, OAuth 2.0
"Basic Auth : provide username:password in Base64 encoded in Authorization header
"lo_http_client->request->set_header_field( name = 'Authorization' value = 'Basic <Base64 encoded value>' ).
CALL METHOD lo_http_client->send
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3
http_invalid_timeout = 4
OTHERS = 5.
IF sy-subrc = 0.
CALL METHOD lo_http_client->receive
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3
OTHERS = 5.
ENDIF.
IF sy-subrc <> 0.
"error handling
ENDIF.
data: lt_fields type TIHTTPNVP.
data(lo_response) = lo_http_client->response.
lo_response->IF_HTTP_ENTITY~GET_HEADER_FIELDS( CHANGING fields = lt_fields ).
*cl_demo_output=>display( lt_fields ).
data(ls_fields) = lt_fields[ name = 'x-csrf-token' ].
data(lv_csrf) = ls_fields-value.
CALL METHOD cl_http_client=>create_by_url
EXPORTING
url = 'https://bpmworkflowruntimeaXXXXXX-XXXXX.hana.ondemand.com/workflow-service/rest/v1/workflow-instances'
IMPORTING
client = lo_http_client
EXCEPTIONS
argument_not_found = 1
plugin_not_active = 2
internal_error = 3
OTHERS = 4.
IF sy-subrc <> 0.
"error handling
ENDIF.
"setting request method
lo_http_client->request->set_method('POST').
"adding headers
lo_http_client->request->set_header_field( name = 'X-CSRF-Token' value = lv_csrf ).
lo_http_client->request->set_header_field( name = 'Content-Type' value = 'application/json' ).
lo_http_client->request->set_header_field( name = 'Accept' value = 'application/json' ).
lo_http_client->request->set_header_field( name = 'Authorization' value = 'Basic XXXXXXXXXXXXXXXXXXXXX' ).
CONCATENATE '{"definitionId": "myworkflowtest",'
'"context": { "PreqItem": "00010", "Material": "000000000000000011",'
'"Plant": 5000, "DelivDate": 25082018,"PrNumber": " " }}' into data(lv_json).
CALL METHOD lo_http_client->request->set_cdata
EXPORTING
data = lv_json.
CALL METHOD lo_http_client->send
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3
http_invalid_timeout = 4
OTHERS = 5.
IF sy-subrc = 0.
CALL METHOD lo_http_client->receive
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3
OTHERS = 5.
ENDIF.
IF sy-subrc <> 0.
"error handling
ENDIF.
response = lo_http_client->response->get_cdata( ).
cl_demo_output=>display( response ).
It looks like you're not passing any cookies between the calls. Cookies contextualise the token that's fetched. Without them, you'll get a 403. See this Q&A for more details. https://answers.sap.com/questions/563171/why-the-business-rules-invoke-rule-service-need-co.html Cheers!
PS you also had your userid and password more or less in plain sight - in the Basic Authentication header, encoded with Base64 (which is simple to decode). So I replaced some of the characters with Xs to obscure it for you.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi DJ,
Thanks for the hint. By adding the cookie handling it is working now.
Hi Sankara,
Like DJ mentioned, you need to use the cookies while calling the API to create workflow instance. You can refer to the following links for the source code and explanation:
https://archive.sap.com/discussions/thread/3786067
Regards,
Sesh
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Sesh,
After making changes to consider cookies, the code works fine. I am pasting the code below so that it will help others. one question that I have.
- What is the best way in this case to create hoop client?. is it by create_by_url or create_by_destiantion? in first case we have to enter basic authentication in base64 format, but in other case we can create a SM59 ( type G ) destination and use that.
DATA: lo_http_client TYPE REF TO if_http_client.
DATA: response TYPE string.
data: lt_fields type TIHTTPNVP.
data: lt_cookies type TIHTTPCKI.<br>
"create HTTP client by url<br>
CALL METHOD cl_http_client=>create_by_url
EXPORTING
url = 'https://bpmworkflowruntimXXXXXXx.hana.ondemand.com'
IMPORTING
client = lo_http_client
EXCEPTIONS
argument_not_found = 1
plugin_not_active = 2
internal_error = 3
OTHERS = 4.<br><br><br>
IF sy-subrc <> 0.
"error handling
ENDIF.
data: l_query type string.
l_query = '/workflow-service/rest/v1/xsrf-token'.<br>
CALL METHOD cl_http_utility=>set_request_uri
EXPORTING
request = lo_http_client->request
uri = l_query.
"setting request method
lo_http_client->propertytype_accept_cookie = if_http_client=>co_enabled.<br>
lo_http_client->request->set_method('GET').<br>
"adding headers
lo_http_client->request->set_header_field( name = 'X-CSRF-Token' value = 'Fetch' ).
lo_http_client->request->set_header_field( name = 'Content-Type' value = 'application/json' ).
lo_http_client->request->set_header_field( name = 'Accept' value = 'application/json' ).
lo_http_client->request->set_header_field( name = 'Authorization' value = 'Basic XXXXXXXXXXU2XXXXXX' ).<br><br>
"Available Security Schemes for productive API Endpoints
"Basic Authentication, OAuth 2.0<br>
"Basic Auth : provide username:password in Base64 encoded in Authorization header
"lo_http_client->request->set_header_field( name = 'Authorization' value = 'Basic <Base64 encoded value>' ).<br>
CALL METHOD lo_http_client->send
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3
http_invalid_timeout = 4
OTHERS = 5.<br>
IF sy-subrc = 0.
CALL METHOD lo_http_client->receive
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3
OTHERS = 5.
ENDIF.<br>
IF sy-subrc <> 0.
"error handling
ENDIF.<br>
data(lo_response) = lo_http_client->response.
response = lo_http_client->response->get_cdata( ).
lo_response->IF_HTTP_ENTITY~GET_HEADER_FIELDS( CHANGING fields = lt_fields ).<br>
data(ls_fields) = lt_fields[ name = 'x-csrf-token' ].
data(lv_csrf) = ls_fields-value.<br>
lo_http_client->response->get_cookies( CHANGING cookies = lt_cookies ).<br>
l_query = '/workflow-service/rest/v1/workflow-instances'.
CALL METHOD cl_http_utility=>set_request_uri
EXPORTING
request = lo_http_client->request
uri = l_query.<br><br><br>
IF sy-subrc <> 0.
"error handling
ENDIF.<br>
"setting request method
lo_http_client->request->set_method('POST').
lo_http_client->propertytype_accept_cookie = if_http_client=>co_enabled.
"adding headers
lo_http_client->request->set_header_field( name = 'X-CSRF-Token' value = lv_csrf ).
lo_http_client->request->set_header_field( name = 'Content-Type' value = 'application/json' ).
lo_http_client->request->set_header_field( name = 'Accept' value = 'application/json' ).
lo_http_client->request->set_header_field( name = 'Authorization' value = 'Basic XXXXXXXXXTXXXXXXXX=' ).<br>
LOOP AT lt_cookies ASSIGNING FIELD-SYMBOL(<cookie>).
lo_http_client->request->set_cookie( name = <cookie>-name
value = <cookie>-value ).
ENDLOOP.<br>
CONCATENATE '{"definitionId": "myworkflowtest",'
'"context": { "PreqItem": "00010", "Material": "000000000000000011",'
'"Plant": 5000, "DelivDate": 25082018, "Quantity" : 13, "PrNumber": " " }}' into data(lv_json).<br><br><br>
CALL METHOD lo_http_client->request->set_cdata
EXPORTING
data = lv_json.<br>
CALL METHOD lo_http_client->send
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3
http_invalid_timeout = 4
OTHERS = 5.<br>
IF sy-subrc = 0.
CALL METHOD lo_http_client->receive
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3
OTHERS = 5.
ENDIF.<br>
IF sy-subrc <> 0.
"error handling
ENDIF.<br>
response = lo_http_client->response->get_cdata( ).
cl_demo_output=>display( response ).
with SM 59 you can safely store your User ID and password . if you use URL, you have to pass the user id and password as indicated earlier by DJ Adams.
so the best practice would be to use the SM59 approach.
Kind Regards,
Vamsi
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
80 | |
9 | |
9 | |
7 | |
7 | |
7 | |
6 | |
5 | |
5 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.