Sockets ABAP Websocket服务器XSRF令牌

Sockets ABAP Websocket服务器XSRF令牌,sockets,abap,Sockets,Abap,我目前正在尝试在SAP应用服务器上设置一个web套接字服务器,作为概念证明。连接到web套接字服务器的应用程序不是UI5或WebDynpro应用程序,而是运行在无头计算机上的中间件程序 根据快速指南,我已经设置了推送通道,并且我有一个对象,其中包含接口方法ON_START,ON_MESSAGE等。我目前正在使用wscat测试接口,您可以从npm获得该接口 当我第一次尝试使用wscat连接到我的服务时,我收到了一个HTTP 500错误 我不确定为什么会出现500错误,所以我尝试通过http和we

我目前正在尝试在SAP应用服务器上设置一个web套接字服务器,作为概念证明。连接到web套接字服务器的应用程序不是UI5或WebDynpro应用程序,而是运行在无头计算机上的中间件程序

根据快速指南,我已经设置了推送通道,并且我有一个对象,其中包含接口方法
ON_START
ON_MESSAGE
等。我目前正在使用
wscat
测试接口,您可以从
npm
获得该接口

当我第一次尝试使用
wscat
连接到我的服务时,我收到了一个HTTP 500错误

我不确定为什么会出现500错误,所以我尝试通过http和web浏览器访问URL以查看发生了什么

500 SAP Internal Server Error

ERROR: Cross-Site Request Forgery (XSRF) check has failed ! (termination: ABORT_MESSAGE_STATE)
我看到网关服务也在使用这些令牌,因此我创建了一个快速网关服务,并使用
X-CSRF-Token:Fetch
发送了一个
GET
请求,但当我尝试使用uri参数
sap XSRF
时,从中获取的令牌不起作用

METHOD check_xsrf.
  DATA: lv_xsrf_token             TYPE string. 
  * 
  * validate XSRF token
  *
  lv_xsrf_token = i_server->request->get_form_field( name = if_http_form_fields_sap=>sap_xsrf ).
IF lv_xsrf_token IS INITIAL.
  lv_xsrf_token = i_server->request->get_header_field( name = if_http_form_fields_sap=>sap_xsrf ).
ENDIF.

IF lv_xsrf_token IS INITIAL.
  r_successful = abap_false.
ELSE.

  CALL METHOD i_server->validate_xsrf_token
    EXPORTING
      token                    = lv_xsrf_token
    IMPORTING
      successful               = r_successful
    EXCEPTIONS
      token_not_found          = 1
      cookie_not_found         = 2
      internal_error           = 3
      called_by_public_service = 4
      OTHERS                   = 5.
  IF sy-subrc <> 0 OR abap_false = r_successful.
    r_successful = abap_false.
  ELSE.
    r_successful = abap_true.
  ENDIF.
ENDIF.

ENDMETHOD.
接下来,我开始调试
CL\u APC\u管理器
函数
HANDLE\u REQUEST
,看看我的请求是否真的出现了。我还想追踪500错误的来源。我已设法将其追溯到
CL\u APC\u管理器
method
CHECK\XSRF

METHOD check_xsrf.
  DATA: lv_xsrf_token             TYPE string. 
  * 
  * validate XSRF token
  *
  lv_xsrf_token = i_server->request->get_form_field( name = if_http_form_fields_sap=>sap_xsrf ).
IF lv_xsrf_token IS INITIAL.
  lv_xsrf_token = i_server->request->get_header_field( name = if_http_form_fields_sap=>sap_xsrf ).
ENDIF.

IF lv_xsrf_token IS INITIAL.
  r_successful = abap_false.
ELSE.

  CALL METHOD i_server->validate_xsrf_token
    EXPORTING
      token                    = lv_xsrf_token
    IMPORTING
      successful               = r_successful
    EXCEPTIONS
      token_not_found          = 1
      cookie_not_found         = 2
      internal_error           = 3
      called_by_public_service = 4
      OTHERS                   = 5.
  IF sy-subrc <> 0 OR abap_false = r_successful.
    r_successful = abap_false.
  ELSE.
    r_successful = abap_true.
  ENDIF.
ENDIF.

ENDMETHOD.
方法检查\u xsrf。
数据:lv_xsrf_令牌类型字符串。
* 
*验证XSRF令牌
*
lv_xsrf_token=i_server->request->get_form_fields(name=if_http_form_fields_sap=>sap_xsrf)。
如果lv_xsrf_令牌为初始值。
lv_xsrf_token=i_server->request->get_header_field(name=if_http_form_fields_sap=>sap_xsrf)。
恩迪夫。
如果lv_xsrf_令牌为初始值。
r_successful=abap_false。
其他的
调用方法i_server->validate_xsrf_令牌
出口
令牌=lv_xsrf_令牌
进口
successful=r_successful
例外情况
未找到令牌=1
cookie\u not\u found=2
内部错误=3
由\u公共\u服务调用\u=4
其他=5。
如果sy subrc 0或abap_false=r_成功。
r_successful=abap_false。
其他的
r_successful=abap_true。
恩迪夫。
恩迪夫。
ENDMETHOD。
如果使用调试器手动跳过此检查,则可以毫无问题地连接到web套接字服务器

然而,在尝试连接之前,我根本不确定我应该如何获得这个令牌。我注意到
XSRF令牌
保存在数据库表
SECURITY\u CONTEXT
中。唯一的问题是,在此表中创建了一个条目,其中包含我尝试连接后需要的键。在之前我需要它,我不确定正确检索令牌的过程是什么

有没有人以前有使用这些产品的经验,可以提供一些帮助?提前谢谢

编辑我正在使用带有Service Pack 4的740版

正确生成标题的“正确”方法是维护表
APC\u CROSS\u ORIGIN
(事务
SAPC\u CROSS\u ORIGIN


WebSocket功能仅在7.40SP5中发布供客户使用,这可能解释了为什么您的系统中没有该表。我建议暂时使用您的解决方案,直到您的系统被修补。

包括在内,我在搜索过程中变得有点不耐烦,最后编写了一个处理程序,该处理程序检索令牌并将其注入到请求中,然后调用标准SAP实现:但这不是一个真正的解决方案,这只是一个黑客行为。您是否维护了跨源白名单(transaction
SAPC_cross_origin
)?我刚刚尝试过,我似乎没有该事务。您的ABAP系统是什么版本和补丁-应该在那里?否则,请尝试直接维护表
APC\u CROSS\u ORIGIN
。哪个修补程序级别?我认为websockets(ABAP频道)只在7.40SP5版本发布,尽管该功能从SP2开始就可用。我猜你可能在旧的支持包上?我看了一下,那张表似乎不是以便条的形式提交的,在这种情况下,您的变通方法可能是唯一的方法。