从ABAP程序触发SCP

2020-09-11 03:11发布

         点击此处--->   EasySAP.com群内免费提供SAP练习系统(在群公告中)

加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)


专家您好,

我正在从ABAP系统触发SCP工作流。 下面是我的代码。 我能够成功获取CSRF令牌值。 但是实际的实例创建没有发生,我收到403 Forbidden错误

注意:我可以使用邮递员触发实例。 因此工作流本身运行正常。

这是我的代码

 *&---------------------------------------------  ------------------------ *
 *&报告Z_TRIGGER_SCP_WORFKLOW
 *&------------------------------------------------  --------------------- *
 *&
 *&------------------------------------------------  --------------------- *
 报告Z_TRIGGER_SCP_WORFKLOW。
 数据:lo_http_client类型参考if_http_client。
 DATA:响应TYPE字符串。
 "通过URL创建HTTP客户端
 " API沙箱的API端点
 呼叫方法cl_http_client => create_by_url
  出口
  url ='https://bpmworkflowruntimeXXXXXea-XXXXX.hana.ondemand.com/workflow-service/rest/v1/xsrf-token'
  输入
  客户端= lo_http_client
  例外情况
  arguments_not_found = 1
  plugin_not_active = 2
  internal_error = 3
  其他= 4。
 如果sy-subrc <> 0。
  "错误处理
 万一。
 "设置请求方法
 lo_http_client-> request-> set_method('GET')。
 "添加标题
 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沙箱的API密钥
 * lo_http_client-> request-> set_header_field(name ='APIKey'value ='Vw0jBxyASfBvXXXXXXXFbEpcTKxizWKr')。
 "用于生产性API端点的可用安全方案
 "基本身份验证,OAuth 2.0
 "基本身份验证:在授权标头中以Base64提供用户名:密码
 " lo_http_client-> request-> set_header_field(名称='授权'值='基本')。
 呼叫方法lo_http_client->发送
  例外情况
  http_communication_failure = 1
  http_invalid_state = 2
  http_processing_failed = 3
  http_invalid_timeout = 4
  其他= 5。
 如果sy-subrc = 0。
  调用方法lo_http_client-> receive
  例外情况
  http_communication_failure = 1
  http_invalid_state = 2
  http_processing_failed = 3
  其他= 5。
 万一。
 如果sy-subrc <> 0。
  "错误处理
 万一。
 数据:lt_fields类型TIHTTPNVP。
 data(lo_response)= lo_http_client->响应。
 lo_response-> IF_HTTP_ENTITY〜GET_HEADER_FIELDS(CHANGING字段= lt_fields)。
 * cl_demo_output => display(lt_fields)。
 data(ls_fields)= lt_fields [name ='x-csrf-token']。
 data(lv_csrf)= ls_fields-value。
 呼叫方法cl_http_client => create_by_url
  出口
  url ='https://bpmworkflowruntimeaXXXXXX-XXXXX.hana.ondemand.com/workflow-service/rest/v1/workflow-instances'
  输入
  客户端= lo_http_client
  例外情况
  arguments_not_found = 1
  plugin_not_active = 2
  internal_error = 3
  其他= 4。
 如果sy-subrc <> 0。
  "错误处理
 万一。
 "设置请求方法
 lo_http_client-> request-> set_method('POST')。
 "添加标题
 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",'
  '"上下文":{" PreqItem":" 00010","材料":" 000000000000000011",'
  '" Plant":5000," DelivDate":25082018," PrNumber":""}}'转换成数据(lv_json)。
 呼叫方法lo_http_client-> request-> set_cdata
  出口
  数据= lv_json。
 呼叫方法lo_http_client->发送
  例外情况
  http_communication_failure = 1
  http_invalid_state = 2
  http_processing_failed = 3
  http_invalid_timeout = 4
  其他= 5。
 如果sy-subrc = 0。
  调用方法lo_http_client-> receive
  例外情况
  http_communication_failure = 1
  http_invalid_state = 2
  http_processing_failed = 3
  其他= 5。
 万一。
 如果sy-subrc <> 0。
  "错误处理
 万一。
 响应= lo_http_client->响应-> get_cdata()。
 cl_demo_output => display(response)。

         点击此处--->   EasySAP.com群内免费提供SAP练习系统(在群公告中)

加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)


专家您好,

我正在从ABAP系统触发SCP工作流。 下面是我的代码。 我能够成功获取CSRF令牌值。 但是实际的实例创建没有发生,我收到403 Forbidden错误

注意:我可以使用邮递员触发实例。 因此工作流本身运行正常。

这是我的代码

 *&---------------------------------------------  ------------------------ *
 *&报告Z_TRIGGER_SCP_WORFKLOW
 *&------------------------------------------------  --------------------- *
 *&
 *&------------------------------------------------  --------------------- *
 报告Z_TRIGGER_SCP_WORFKLOW。
 数据:lo_http_client类型参考if_http_client。
 DATA:响应TYPE字符串。
 "通过URL创建HTTP客户端
 " API沙箱的API端点
 呼叫方法cl_http_client => create_by_url
  出口
  url ='https://bpmworkflowruntimeXXXXXea-XXXXX.hana.ondemand.com/workflow-service/rest/v1/xsrf-token'
  输入
  客户端= lo_http_client
  例外情况
  arguments_not_found = 1
  plugin_not_active = 2
  internal_error = 3
  其他= 4。
 如果sy-subrc <> 0。
  "错误处理
 万一。
 "设置请求方法
 lo_http_client-> request-> set_method('GET')。
 "添加标题
 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沙箱的API密钥
 * lo_http_client-> request-> set_header_field(name ='APIKey'value ='Vw0jBxyASfBvXXXXXXXFbEpcTKxizWKr')。
 "用于生产性API端点的可用安全方案
 "基本身份验证,OAuth 2.0
 "基本身份验证:在授权标头中以Base64提供用户名:密码
 " lo_http_client-> request-> set_header_field(名称='授权'值='基本')。
 呼叫方法lo_http_client->发送
  例外情况
  http_communication_failure = 1
  http_invalid_state = 2
  http_processing_failed = 3
  http_invalid_timeout = 4
  其他= 5。
 如果sy-subrc = 0。
  调用方法lo_http_client-> receive
  例外情况
  http_communication_failure = 1
  http_invalid_state = 2
  http_processing_failed = 3
  其他= 5。
 万一。
 如果sy-subrc <> 0。
  "错误处理
 万一。
 数据:lt_fields类型TIHTTPNVP。
 data(lo_response)= lo_http_client->响应。
 lo_response-> IF_HTTP_ENTITY〜GET_HEADER_FIELDS(CHANGING字段= lt_fields)。
 * cl_demo_output => display(lt_fields)。
 data(ls_fields)= lt_fields [name ='x-csrf-token']。
 data(lv_csrf)= ls_fields-value。
 呼叫方法cl_http_client => create_by_url
  出口
  url ='https://bpmworkflowruntimeaXXXXXX-XXXXX.hana.ondemand.com/workflow-service/rest/v1/workflow-instances'
  输入
  客户端= lo_http_client
  例外情况
  arguments_not_found = 1
  plugin_not_active = 2
  internal_error = 3
  其他= 4。
 如果sy-subrc <> 0。
  "错误处理
 万一。
 "设置请求方法
 lo_http_client-> request-> set_method('POST')。
 "添加标题
 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",'
  '"上下文":{" PreqItem":" 00010","材料":" 000000000000000011",'
  '" Plant":5000," DelivDate":25082018," PrNumber":""}}'转换成数据(lv_json)。
 呼叫方法lo_http_client-> request-> set_cdata
  出口
  数据= lv_json。
 呼叫方法lo_http_client->发送
  例外情况
  http_communication_failure = 1
  http_invalid_state = 2
  http_processing_failed = 3
  http_invalid_timeout = 4
  其他= 5。
 如果sy-subrc = 0。
  调用方法lo_http_client-> receive
  例外情况
  http_communication_failure = 1
  http_invalid_state = 2
  http_processing_failed = 3
  其他= 5。
 万一。
 如果sy-subrc <> 0。
  "错误处理
 万一。
 响应= lo_http_client->响应-> get_cdata()。
 cl_demo_output => display(response)。
付费偷看设置
发送
5条回答
亦是此间程序员
1楼 · 2020-09-11 03:55.采纳回答

您似乎在两次通话之间没有传递任何Cookie。 Cookies将获取的令牌上下文化。 没有它们,您将得到403。有关更多详细信息,请参阅此问答。 https://answers .sap.com/questions/563171/why-the-business-rules-invoke-rule-service-need-co.html 干杯!

PS在基本身份验证标头中也具有或多或少的用户名和密码-在基本身份验证标头中,该标头使用Base64编码(易于解码)。 因此,我用Xs替换了一些字符,以便为您遮盖它。

Baoming ROSE
2楼-- · 2020-09-11 04:10

嗨,DJ,

感谢您的提示。 通过添加cookie处理,它现在可以正常工作。

小灯塔
3楼-- · 2020-09-11 04:00

您好,Sankara,

就像提到的DJ一样,您需要在调用API来创建工作流实例时使用cookie。 您可以参考以下链接获取源代码和说明:

https://archive.sap.com/discussions/thread/3786067

https://blogs.sap.com/2017/08/04/regarding-cookie-manipulation-in-cl_http_client-to-avoid-csrf-token-validation-failure-issue /

此致

Sesh

SAP浪
4楼-- · 2020-09-11 04:13

嗨,Sesh,

进行更改以考虑cookie后,代码可以正常工作。 我在下面粘贴代码,以帮助他人。 我有一个问题。

-在这种情况下,创建箍客户端的最佳方法是什么? 是通过create_by_url还是create_by_destiantion? 在第一种情况下,我们必须以base64格式输入基本身份验证,但是在其他情况下,我们可以创建一个SM59(类型G)目标并使用该目标。

数据:lo_http_client类型参考if_http_client。
 DATA:响应TYPE字符串。
 数据:lt_fields类型TIHTTPNVP。
 数据:lt_cookies类型TIHTTPCKI。
"通过url创建HTTP客户端
呼叫方法cl_http_client => create_by_url 出口 url ='https://bpmworkflowruntimXXXXXXx.hana.ondemand.com' 输入 客户端= lo_http_client 例外情况 arguments_not_found = 1 plugin_not_active = 2 internal_error = 3 其他=4。


如果sy-subrc <> 0。 "错误处理 万一。 数据:l_query类型字符串。 l_query ='/workflow-service/rest/v1/xsrf-token'。
呼叫方法cl_http_utility => set_request_uri 出口 请求= lo_http_client->请求 uri = l_query。 "设置请求方法 lo_http_client-> propertytype_accept_cookie = if_http_client => co_enabled。
lo_http_client-> request-> set_method('GET')。
"添加标题 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')。

"用于生产性API端点的可用安全方案 "基本身份验证,OAuth 2.0
"基本身份验证:在授权标头中以Base64提供用户名:密码 " lo_http_client-> request-> set_header_field(name ='Authorization'value ='Basic ')。
呼叫方法lo_http_client->发送 例外情况 http_communication_failure = 1 http_invalid_state = 2 http_processing_failed = 3 http_invalid_timeout = 4 其他=5。
如果sy-subrc = 0。 调用方法lo_http_client-> receive 例外情况 http_communication_failure = 1 http_invalid_state = 2 http_processing_failed = 3 其他= 5。 ENDIF。
如果sy-subrc <> 0。 "错误处理 ENDIF。
data(lo_response)= lo_http_client->响应。 响应= lo_http_client->响应-> get_cdata()。 lo_response-> IF_HTTP_ENTITY〜GET_HEADER_FIELDS(CHANGING字段= lt_fields)。
data(ls_fields)= lt_fields [name ='x-csrf-token']。 data(lv_csrf)= ls_fields-value。
lo_http_client->响应-> get_cookies(更改cookie = lt_cookies)。
l_query ='/workflow-service/rest/v1/workflow-instances'。 呼叫方法cl_http_utility => set_request_uri 出口 请求= lo_http_client->请求 uri = l_query。


如果sy-subrc <> 0。 "错误处理 ENDIF。
"设置请求方法 lo_http_client-> request-> set_method('POST')。 lo_http_client-> propertytype_accept_cookie = if_http_client => co_enabled。 "添加标题 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 =')。
在lt_cookies分配字段符号()处循环播放。 lo_http_client-> request-> set_cookie(name = -name 值= -值)。 ENDLOOP。
CONCATENATE'{" definitionId":" myworkflowtest",' '"上下文":{" PreqItem":" 00010","材料":" 000000000000000011",' '" Plant":5000," DelivDate":25082018," Quantity":13," PrNumber":""}}'转换成数据(lv_json)。


呼叫方法lo_http_client-> request-> set_cdata 出口 数据= lv_json。
呼叫方法lo_http_client->发送 例外情况 http_communication_failure = 1 http_invalid_state = 2 http_processing_failed = 3 http_invalid_timeout = 4 其他=5。
如果sy-subrc = 0。 调用方法lo_http_client-> receive 例外情况 http_communication_failure = 1 http_invalid_state = 2 http_processing_failed = 3 其他= 5。 ENDIF。
如果sy-subrc <> 0。 "错误处理 ENDIF。
响应= lo_http_client->响应-> get_cdata()。 cl_demo_output => display(response)。
hengyuye
5楼-- · 2020-09-11 04:09

使用SM 59,您可以安全地存储用户ID和密码。 如果使用URL,则必须传递DJ Adams先前指示的用户ID和密码。

因此,最佳实践是使用SM59方法。

亲切的问候,

Vamsi

一周热门 更多>