SAP Cloud SDK for Javaを使用して、S / 4のSalesOrderAPIでCRUDを実行しています。Postmanからこれらのアクションを実行できるという点で、すべてがうまく機能します。ただし、Postmanからのこれらのリクエストは、このブログ投稿で概説されているように、csrfトークンを取得するための事前リクエストスクリプトを含める場合にのみ機能します。
ブログ投稿で概説されている事前リクエストスクリプトなしでリクエストを実行すると、「403Forbidden」が表示されます。私が言ったように、これはPostmanから機能しますが、たとえば別のアプリケーションから要求を行っている場合など、このスクリプトを必要とせずにこれを処理する方法を理解したいと思います。SDKを使用すると、アプリケーションコードからこれをなんとかして処理できますか?多分私は何かが欠けています。
御時間ありがとうございます。
編集:私はPostmanから直接S / 4にリクエストを行っていません。CloudSDKを使用してS / 4にリクエストを送信するアプリをデプロイしました。事前リクエストスクリプトを使用してCSFRトークンをフェッチし、送信する前にリクエストに添付すると機能しますが、そうでない場合は403です。したがって、Postmanを使用していないが、フォームに入力してこのリクエストを送信するためにUIを使用していると想像した場合、あなたが提案したように、このトークンについて心配する必要はないということを理解しています。 SDKとVDMがこれを処理するはずです。これは私が理解するのに苦労していることです。
これはサーブレットコードです。
@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);
}
}
SDKのバージョン3.16.1を使用しており、マニフェストでSDKのログレベルをDEBUGに設定しています。
SET_LOGGING_LEVEL: '{ROOT: INFO, com.sap.cloud.sdk: DEBUG}'
ログバックでDEBUGへのログレベル
リクエストからプレリクエストスクリプトを削除して送信すると、403レスポンスが返され、ログに次のメッセージが表示されます。
"logger": "com.sap.cloud.sdk.service.prov.api.security.AuthorizationListener"、 "thread": "http-nio-0.0.0.0-8080-exec-4"、 "level": "DEBUG "、" category ":[]、" msg ":"ユーザープリンシパルの読み取り "
"logger": "com.sap.cloud.sdk.service.prov.api.security.AuthorizationListener"、 "thread": "http-nio-0.0.0.0-8080-exec-4"、 "level": "DEBUG "、" category ":[]、" msg ":"リクエストが終了したため、承認を破棄しています。 " }
"logger": "com.sap.cloud.sdk.service.prov.api.security.AuthorizationService"、 "thread": "http-nio-0.0.0.0-8080-exec-4"、 "level": "DEBUG "、" category ":[]、" msg ":"認証JWTトークンを破棄しています。 " }
他の回答はアプリからS / 4への通信に焦点を当てており、ユーザー(Postmanなど)からアプリへの通信を意味することを明確にするために質問を調整したので、いくつかの追加情報を提供します。
他の回答で述べたように、S / 4システム(または任意のODataエンドポイント)へのCSRF処理は、ODataVDM側で自動的に処理されます。
現在発生しているのは、SAP Cloud SDK Maven Archetypesの安全なデフォルト構成であり、RestCsrfPreventionFilter
デフォルトでアクティブ化されています。このフィルターはGET
、リクエストの前にCSRFトークンをフェッチするように要求することで、すべての非エンドポイントをCSRFから自動的に保護します。これは、バックグラウンドでのS / 4システムへのODataVDM呼び出しとはまったく関係ありません。
問題を解決するために、次の3つのステップがあります。
GET
代わりにエンドポイントを使用するPOST
RestCsrfPreventionFilter
一時的に削除しますweb.xml
RestCsrfPreventionFilter
:https://tomcat.apache.org/tomcat-8.5-doc/api/org/apache/catalina/filters/RestCsrfPreventionFilter.htmlこの記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加