【发布时间】:2020-04-29 22:25:50
【问题描述】:
我正在使用 SAP Cloud SDK for Java 在 S/4 中对 SalesOrder API 执行 CRUD。一切都很好,因为我可以从 Postman 执行这些操作。但是,只有在我包含预请求脚本以获取 this blog post 中所述的 csrf 令牌时,来自 Postman 的这些请求才有效
如果我在没有博客文章中概述的预请求脚本的情况下运行请求,我会收到“403 Forbidden”。正如我所说,它适用于 Postman,但我想了解如何在不需要此脚本的情况下处理它,例如,如果我正在从另一个应用程序发出请求。 SDK是否允许我以某种方式从应用程序代码处理这个问题。也许我错过了什么。
感谢您的宝贵时间。
编辑: 我不是直接从 Postman 向 S/4 提出请求。我部署了一个应用程序,它使用 Cloud SDK 向 S/4 发出请求。如果我在发送之前使用预请求脚本获取 CSFR 令牌并将其附加到请求中,则它可以工作,但如果我不使用,则为 403。所以,如果我们想象我不是在使用 Postman,而是在某个地方使用一些 ui 来填写表格并发送这个请求,我的理解是,我不应该像你建议的那样担心这个令牌,我的中间服务使用SDK 和 VDM 应该为我处理这个问题。这是我很难理解的。
这是servlet代码:
@Override
protected void doPost(final HttpServletRequest request, final HttpServletResponse response)
throws ServletException, IOException {
String body = IOUtils.toString(request.getReader());
JSONObject so = new JSONObject(body);
String distributionChannel = so.get("DistributionChannel").toString();
String salesOrderType = so.get("SalesOrderType").toString();
String salesOrganization = so.get("SalesOrganization").toString();
String soldToParty = so.get("SoldToParty").toString();
String organizationDivision = so.get("OrganizationDivision").toString();
String material = so.get("Material").toString();
String requestedQuantityUnit = so.get("RequestedQuantityUnit").toString();
SalesOrderItem salesOrderItem = SalesOrderItem.builder()
.material(material)
.requestedQuantityUnit(requestedQuantityUnit).build();
SalesOrder salesOrder = SalesOrder.builder()
.salesOrderType(salesOrderType)
.distributionChannel(distributionChannel)
.salesOrganization(salesOrganization)
.soldToParty(soldToParty)
.organizationDivision(organizationDivision)
.item(salesOrderItem)
.build();
try {
final ErpHttpDestination destination = DestinationAccessor.getDestination(DESTINATION_NAME).asHttp()
.decorate(DefaultErpHttpDestination::new);
final SalesOrder storedSalesOrder = new CreateSalesOrderCommand(destination, new DefaultSalesOrderService(),
salesOrder).execute();
response.setStatus(HttpServletResponse.SC_CREATED);
response.setContentType("application/json");
response.getWriter().write(new Gson().toJson(storedSalesOrder));
logger.info("Succeeded to CREATE {} sales order", storedSalesOrder);
} catch (final Exception e) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
logger.error(e.getMessage(), e);
logger.error("Failed to CREATE sales order", e);
}
}
还有 CreateSalesOrder 命令:
public SalesOrder execute() {
return ResilienceDecorator.executeSupplier(this::run, myResilienceConfig);
}
protected SalesOrder run() {
try {
return salesOrderService.createSalesOrder(salesOrder).execute(destination);
} catch (final ODataException e) {
throw new ResilienceRuntimeException(e);
}
}
我使用的是 3.16.1 版本的 SDK,并已在清单中将 SDK 的日志记录级别设置为 DEBUG:
SET_LOGGING_LEVEL: '{ROOT: INFO, com.sap.cloud.sdk: DEBUG}'
在 logback 中将日志级别记录为 DEBUG
如果我从请求中删除预请求脚本并发送它,我会收到 403 响应,并且日志会显示以下消息:
"logger":"com.sap.cloud.sdk.service.prov.api.security.AuthorizationListener","thread":"http-nio-0.0.0.0-8080-exec-4","level" :"DEBUG","categories":[],"msg":"正在阅读 用户主体”
"logger":"com.sap.cloud.sdk.service.prov.api.security.AuthorizationListener","thread":"http-nio-0.0.0.0-8080-exec-4","level" :"DEBUG","categories":[],"msg":"在请求结束时销毁授权。" }
"logger":"com.sap.cloud.sdk.service.prov.api.security.AuthorizationService","thread":"http-nio-0.0.0.0-8080-exec-4","level" :"DEBUG","categories":[],"msg":"销毁授权 JWT 令牌。" }
【问题讨论】:
标签: sap-cloud-platform sap-cloud-sdk s4hana