【发布时间】:2015-08-13 08:57:58
【问题描述】:
我目前正尝试在 SAP 应用程序服务器上设置一个 web-socket 服务器作为概念证明。连接到 web-socket 服务器的应用程序不会是 UI5 或 WebDynpro 应用程序,而只是在无头计算机上运行的中间件程序。
按照快速指南,我已经设置了推送通道,并且我有一个带有接口方法ON_START、ON_MESSAGE 等的对象。我目前正在使用wscat 测试接口,您可以从中获取npm。
当我第一次尝试使用 wscat 连接到我的服务时,我收到了 HTTP 500 错误。
我不确定为什么会收到 500 错误,因此我尝试通过 http 和网络浏览器访问该 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。
接下来,我开始调试 CL_APC_MANAGER 函数 HANDLE_REQUEST 以查看我的请求是否进入。我还想追踪 500 错误的来源。我设法将其追溯到CL_APC_MANAGER 方法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.
如果我使用调试器手动跳过此检查,则可以毫无问题地连接到我的 web-socket 服务器。
但是,我完全不确定在尝试连接之前我应该如何获得这个令牌。我注意到XSRF Tokens 保存在数据库表SECURITY_CONTEXT 中。唯一的问题是在此表中创建了一个条目,其中包含我尝试连接后需要拥有的密钥。我需要它之前,我不确定正确检索令牌的过程是什么。
有没有使用过这些的经验的人可以提供一些启示?提前致谢。
编辑我使用的是带有 Service Pack 4 的 740 版。
【问题讨论】:
-
要包括在内,我最终在搜索中有点不耐烦了,最后编写了一个处理程序来检索令牌并将其注入请求中,然后调用标准 SAP 实现:gist.github.com/anonymous/7c784568f69239ef722f 但是这不是一个真正的解决方案,它只是一个 hack。
-
你是否维护了跨域白名单(事务
SAPC_CROSS_ORIGIN)? -
我刚试了,好像没有那个交易。
-
您的 ABAP 系统是什么版本和补丁 - 它应该在那里?否则,尝试直接维护表
APC_CROSS_ORIGIN。 -
哪个补丁级别?我认为 websockets(ABAP 通道)仅在 7.40 SP5 中发布,尽管该功能自 SP2 起可用。我猜您可能使用的是较旧的支持包?我快速浏览了一下,该表格似乎没有在便笺中提供,在这种情况下,您的解决方法可能是唯一的方法。