CSRF token validation failed - SAP Business Application Studio destination with on-premise destination
See original GitHub issueDescribe the bug Similar issue as #617 from my point of view.
Debugging a CAP + Cloud SDK app in BAS using a destination with type on-premise fails with βCSRF Token validation failedβ (OData read/select works) while the deployed app in CF works fine.
Happy to provide more insights/guidance/explanation if necessary. Thanks already in advance π
To Reproduce Steps to reproduce the behavior:
-
git clone https://github.tools.sap/D063937/cloud-sdk-destination-issue.git
in BAS -
npm install
-
mbt build && f deploy mta_archives/test_1.0.0.mtar
-
Create a run configuration of type CAP and connect to the destination (should start the built in proxy)
-
Bind the services from the previously deployed MTA (connectivity, destination, xsuaa) to your local app.
-
merge the destination + VCAP_services information into one .env file (usually different files) and double check that the .env file in the .vscode/launch.jsonis properly set.
-
Start the run configuration
-
Go to /test/requests.http and send the request to fire the getAllBupa function -> Business Partner from S/4 on prem will be listed in the console
-
send the request to fire the insertBupa_ function. This wonβt work.
-
Do the same with the URL for the deployed app and watch the logs with cf logs test-srv - you will see that the CSRF token handle works perfectly as expected.
Expected behavior Cloud SDK takes care of the full CSRF token handling, no matter if thereβs a proxy of BAS between the connectivity the service and the locally running app in BAS or not.
Screenshots If applicable, add screenshots to help explain your problem.
Used Versions:
- node: v10.23.1
- npm: 6.14.10
- SAP Cloud SDK version: β@sap/cloud-sdk-vdm-business-partner-serviceβ: β^1.24.0β,
Code Examples https://github.tools.sap/D063937/cloud-sdk-destination-issue/blob/master/srv/catalog-service.js#L10-L18
Log file
Log output in BAS:
[cds] - GET /test/insertBupa()
{"message":"Attempting to retrieve destination from environment variable.","level":"info","custom_fields":{"package":"core","messageContext":"env-destination-accessor"},"logger":"sap-cloud-sdk-logger","timestamp":"2021-02-23T21:29:53.890Z","msg":"Attempting to retrieve destination from environment variable.","written_ts":1614115793890,"written_at":"2021-02-23T21:29:53.890Z"}
{"message":"Environment variable 'destinations' is set. Destinations will be read from this variable. This is discouraged for a productive application! Unset the variable to read destinations from the destination service on SAP Cloud Platform.","level":"warn","custom_fields":{"package":"core","messageContext":"env-destination-accessor"},"logger":"sap-cloud-sdk-logger","timestamp":"2021-02-23T21:29:53.891Z","msg":"Environment variable 'destinations' is set. Destinations will be read from this variable. This is discouraged for a productive application! Unset the variable to read destinations from the destination service on SAP Cloud Platform.","written_ts":1614115793891,"written_at":"2021-02-23T21:29:53.891Z"}
{"message":"Try to fetch http_proxy or HTTP_PROXY from the process env. Found value is http://127.0.0.1:8887","level":"info","custom_fields":{"package":"core","messageContext":"proxy-util"},"logger":"sap-cloud-sdk-logger","timestamp":"2021-02-23T21:29:53.892Z","msg":"Try to fetch http_proxy or HTTP_PROXY from the process env. Found value is http://127.0.0.1:8887","written_ts":1614115793892,"written_at":"2021-02-23T21:29:53.892Z"}
{"message":"Try to fetch http_proxy or HTTP_PROXY from the process env. Found value is http://127.0.0.1:8887","level":"info","custom_fields":{"package":"core","messageContext":"proxy-util"},"logger":"sap-cloud-sdk-logger","timestamp":"2021-02-23T21:29:53.892Z","msg":"Try to fetch http_proxy or HTTP_PROXY from the process env. Found value is http://127.0.0.1:8887","written_ts":1614115793892,"written_at":"2021-02-23T21:29:53.892Z"}
{"message":"Proxy settings for http are found in environment variables.","level":"info","custom_fields":{"package":"core","messageContext":"proxy-util"},"logger":"sap-cloud-sdk-logger","timestamp":"2021-02-23T21:29:53.893Z","msg":"Proxy settings for http are found in environment variables.","written_ts":1614115793893,"written_at":"2021-02-23T21:29:53.893Z"}
{"message":"Try to fetch http_proxy or HTTP_PROXY from the process env. Found value is http://127.0.0.1:8887","level":"info","custom_fields":{"package":"core","messageContext":"proxy-util"},"logger":"sap-cloud-sdk-logger","timestamp":"2021-02-23T21:29:53.893Z","msg":"Try to fetch http_proxy or HTTP_PROXY from the process env. Found value is http://127.0.0.1:8887","written_ts":1614115793893,"written_at":"2021-02-23T21:29:53.893Z"}
{"message":"Successfully retrieved destination from environment variable.","level":"info","custom_fields":{"package":"core","messageContext":"env-destination-accessor"},"logger":"sap-cloud-sdk-logger","timestamp":"2021-02-23T21:29:53.894Z","msg":"Successfully retrieved destination from environment variable.","written_ts":1614115793894,"written_at":"2021-02-23T21:29:53.894Z"}
{"message":"The custom headers are provided with the keys: x-csrf-token. These keys will overwrite the headers created by the SDK.","level":"warn","custom_fields":{"package":"core","messageContext":"http-client"},"logger":"sap-cloud-sdk-logger","timestamp":"2021-02-23T21:29:53.898Z","msg":"The custom headers are provided with the keys: x-csrf-token. These keys will overwrite the headers created by the SDK.","written_ts":1614115793898,"written_at":"2021-02-23T21:29:53.898Z"}
{"message":"Destination did not return a CSRF token. This may cause a failure when sending the OData request.","level":"warn","custom_fields":{"package":"core","messageContext":"csrf-token-header"},"logger":"sap-cloud-sdk-logger","timestamp":"2021-02-23T21:29:54.659Z","msg":"Destination did not return a CSRF token. This may cause a failure when sending the OData request.","written_ts":1614115794659,"written_at":"2021-02-23T21:29:54.659Z"}
{"message":"CSRF header response does not include cookies.","level":"warn","custom_fields":{"package":"core","messageContext":"csrf-token-header"},"logger":"sap-cloud-sdk-logger","timestamp":"2021-02-23T21:29:54.659Z","msg":"CSRF header response does not include cookies.","written_ts":1614115794659,"written_at":"2021-02-23T21:29:54.659Z"}
{"message":"The custom headers are provided with the keys: content-type,accept. These keys will overwrite the headers created by the SDK.","level":"warn","custom_fields":{"package":"core","messageContext":"http-client"},"logger":"sap-cloud-sdk-logger","timestamp":"2021-02-23T21:29:54.660Z","msg":"The custom headers are provided with the keys: content-type,accept. These keys will overwrite the headers created by the SDK.","written_ts":1614115794660,"written_at":"2021-02-23T21:29:54.660Z"}
- (some lines cut off in between)
needReadable: true,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
paused: false,
emitClose: false,
autoDestroy: false,
destroyed: false,
defaultEncoding: 'utf8',
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null },
readable: true,
_events:
[Object: null prototype] {
end: [Function: onReadableStreamEnd],
free: { [Function: bound onceWrapper] listener: [Function] },
drain: [Function: ondrain],
error: [Function: socketErrorListener],
close: [Function: socketCloseListener],
finish:
{ [Function: bound onceWrapper] listener: [Function: destroy] } },
_eventsCount: 6,
_maxListeners: undefined,
_writableState:
WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: true,
needDrain: false,
ending: true,
ended: true,
finished: false,
destroyed: false,
decodeStrings: false,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: false,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 1,
prefinished: false,
errorEmitted: false,
emitClose: false,
autoDestroy: false,
bufferedRequestCount: 0,
corkedRequestsFree:
{ next:
{ next: null,
entry: null,
finish: [Function: bound onCorkedFinish] },
entry: null,
finish: [Function: bound onCorkedFinish] } },
writable: false,
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: null,
_server: null,
parser: null,
_httpMessage: [Circular],
[Symbol(asyncId)]: 402,
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0 },
connection:
Socket {
connecting: false,
_hadError: false,
_handle:
TCP {
reading: true,
onread: [Function: onStreamRead],
onconnection: null,
[Symbol(owner)]: [Circular] },
_parent: null,
_host: null,
_readableState:
ReadableState {
objectMode: false,
highWaterMark: 16384,
buffer: BufferList { head: null, tail: null, length: 0 },
length: 0,
pipes: null,
pipesCount: 0,
flowing: true,
ended: false,
endEmitted: false,
reading: true,
sync: false,
needReadable: true,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
paused: false,
emitClose: false,
autoDestroy: false,
destroyed: false,
defaultEncoding: 'utf8',
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null },
readable: true,
_events:
[Object: null prototype] {
end: [Function: onReadableStreamEnd],
free: { [Function: bound onceWrapper] listener: [Function] },
drain: [Function: ondrain],
error: [Function: socketErrorListener],
close: [Function: socketCloseListener],
finish:
{ [Function: bound onceWrapper] listener: [Function: destroy] } },
_eventsCount: 6,
_maxListeners: undefined,
_writableState:
WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: true,
needDrain: false,
ending: true,
ended: true,
finished: false,
destroyed: false,
decodeStrings: false,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: false,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 1,
prefinished: false,
errorEmitted: false,
emitClose: false,
autoDestroy: false,
bufferedRequestCount: 0,
corkedRequestsFree:
{ next:
{ next: null,
entry: null,
finish: [Function: bound onCorkedFinish] },
entry: null,
finish: [Function: bound onCorkedFinish] } },
writable: false,
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: null,
_server: null,
parser: null,
_httpMessage: [Circular],
[Symbol(asyncId)]: 402,
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0 },
_header:
'PATCH http://businesspartner.dest/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner(BusinessPartner=%27HARUT%27) HTTP/1.1\r\nAccept: application/json\r\nContent-Type: application/json\r\nUser-Agent: axios/0.21.1\r\nContent-Length: 48\r\nHost: businesspartner.dest\r\nConnection: close\r\n\r\n',
_onPendingData: [Function: noopPendingOutput],
agent:
HttpProxyAgent {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
timeout: null,
maxFreeSockets: 1,
maxSockets: 1,
maxTotalSockets: Infinity,
sockets: {},
freeSockets: {},
requests: {},
options: {},
secureProxy: false,
proxy:
{ protocol: 'http:',
slashes: true,
auth: null,
host: '127.0.0.1',
port: 8887,
hostname: '127.0.0.1',
hash: null,
search: null,
query: null,
href: 'http://127.0.0.1:8887/' },
promisifiedCallback: [Function: callback] },
socketPath: undefined,
timeout: undefined,
method: 'PATCH',
insecureHTTPParser: undefined,
path:
'http://businesspartner.dest/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner(BusinessPartner=%27HARUT%27)',
_ended: true,
res:
IncomingMessage {
_readableState:
ReadableState {
objectMode: false,
highWaterMark: 16384,
buffer: BufferList { head: null, tail: null, length: 0 },
length: 0,
pipes: null,
pipesCount: 0,
flowing: true,
ended: true,
endEmitted: true,
reading: false,
sync: true,
needReadable: false,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
paused: false,
emitClose: true,
autoDestroy: false,
destroyed: false,
defaultEncoding: 'utf8',
awaitDrain: 0,
readingMore: true,
decoder: null,
encoding: null },
readable: false,
_events:
[Object: null prototype] {
end: [ [Function: responseOnEnd], [Function: handleStreamEnd] ],
data: [Function: handleStreamData],
error: [Function: handleStreamError] },
_eventsCount: 3,
_maxListeners: undefined,
socket:
Socket {
connecting: false,
_hadError: false,
_handle:
TCP {
reading: true,
onread: [Function: onStreamRead],
onconnection: null,
[Symbol(owner)]: [Circular] },
_parent: null,
_host: null,
_readableState:
ReadableState {
objectMode: false,
highWaterMark: 16384,
buffer: BufferList { head: null, tail: null, length: 0 },
length: 0,
pipes: null,
pipesCount: 0,
flowing: true,
ended: false,
endEmitted: false,
reading: true,
sync: false,
needReadable: true,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
paused: false,
emitClose: false,
autoDestroy: false,
destroyed: false,
defaultEncoding: 'utf8',
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null },
readable: true,
_events:
[Object: null prototype] {
end: [Function: onReadableStreamEnd],
free: { [Function: bound onceWrapper] listener: [Function] },
drain: [Function: ondrain],
error: [Function: socketErrorListener],
close: [Function: socketCloseListener],
finish:
{ [Function: bound onceWrapper] listener: [Function: destroy] } },
_eventsCount: 6,
_maxListeners: undefined,
_writableState:
WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: true,
needDrain: false,
ending: true,
ended: true,
finished: false,
destroyed: false,
decodeStrings: false,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: false,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 1,
prefinished: false,
errorEmitted: false,
emitClose: false,
autoDestroy: false,
bufferedRequestCount: 0,
corkedRequestsFree:
{ next:
{ next: null,
entry: null,
finish: [Function: bound onCorkedFinish] },
entry: null,
finish: [Function: bound onCorkedFinish] } },
writable: false,
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: null,
_server: null,
parser: null,
_httpMessage: [Circular],
[Symbol(asyncId)]: 402,
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0 },
connection:
Socket {
connecting: false,
_hadError: false,
_handle:
TCP {
reading: true,
onread: [Function: onStreamRead],
onconnection: null,
[Symbol(owner)]: [Circular] },
_parent: null,
_host: null,
_readableState:
ReadableState {
objectMode: false,
highWaterMark: 16384,
buffer: BufferList { head: null, tail: null, length: 0 },
length: 0,
pipes: null,
pipesCount: 0,
flowing: true,
ended: false,
endEmitted: false,
reading: true,
sync: false,
needReadable: true,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
paused: false,
emitClose: false,
autoDestroy: false,
destroyed: false,
defaultEncoding: 'utf8',
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null },
readable: true,
_events:
[Object: null prototype] {
end: [Function: onReadableStreamEnd],
free: { [Function: bound onceWrapper] listener: [Function] },
drain: [Function: ondrain],
error: [Function: socketErrorListener],
close: [Function: socketCloseListener],
finish:
{ [Function: bound onceWrapper] listener: [Function: destroy] } },
_eventsCount: 6,
_maxListeners: undefined,
_writableState:
WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: true,
needDrain: false,
ending: true,
ended: true,
finished: false,
destroyed: false,
decodeStrings: false,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: false,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 1,
prefinished: false,
errorEmitted: false,
emitClose: false,
autoDestroy: false,
bufferedRequestCount: 0,
corkedRequestsFree:
{ next:
{ next: null,
entry: null,
finish: [Function: bound onCorkedFinish] },
entry: null,
finish: [Function: bound onCorkedFinish] } },
writable: false,
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: null,
_server: null,
parser: null,
_httpMessage: [Circular],
[Symbol(asyncId)]: 402,
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0 },
httpVersionMajor: 1,
httpVersionMinor: 1,
httpVersion: '1.1',
complete: true,
headers:
{ 'content-length': '28',
'content-type': 'text/plain; charset=utf-8',
date: 'Tue, 23 Feb 2021 21:29:55 GMT',
'sap-perf-fesrec': '20749.000000',
'sap-processing-info':
'ODataBEP=,crp=,RAL=,st=,MedCacheHub=,codeployed=X,softstate=',
'sap-server': 'true',
'set-cookie':
[ 'ARBE=b495e4ffe60015994d0fa318954b96f235a5706c18ad8aeca366ae15c23680b8d3e794ee3403ca4a22e6611b885ec55cb13394db382a9e54f5c6a710ab25525d9fc6e186192c55114450b0be5d24c4dcaef6521c562edb3aa942eafac59abc85391cdb0966817bc55b4a2cbf766f69d732c973817bd3088b6a8f4b4ac1ee95f2e1d5d1f1963d0f0fe74603e42030843d875337c75d0bac4854b8e1354aea20805a75a839cbfc52baa810ff58df6937e7eb5dbf99f35cc2c103eb2495caad5f1b96b05374d9985999d350284dbdc641f6196ca26a444f602f93a4162894520a975df182428e3c17fc5f434842588c6fd326833b9c72e11a0d4c4d81ea9e77f1a196c250d801b14e0d5c8e4e4c932f02ca47989bfd95cedf8b89adc9e61231321649793401716fac36efd05825e76b121c973dbf021e1d2922b389eb34215187edadb4da447d1a542f43ed6f04bb850798d983cc9cd636d998c029a886c0172680dbd746d6f2b5d917e0382b19b854bf3c262d1ec3be4c13974283edd92309e9c2010e7985abe20334e440a935aef1430906afc681b94abd8331f329eb3d95f60e68f459550f53395113ffb75104167746ee783484b1eecf6410a0d7ff32e3fc3b3e24435bbbea79d5a716cd868114fcdcbbfa56c9c08f550512332efd97e0b9a7aa081c9284a9702f6433f0ea3e6f643dfaa0c6ade9e7a157492bed1985dbdcb5f780cd4f7fbbce6429c1c4cd444fcad7d4f1efa056c0eb5ecf62ec686d3f4c4e95c83704acf9b28e098a65f1c3dea5c008674868611bd0391659c1bdbecd6790801649e4898814035d7a84b624463e84910d335d52435bc6c2c72de4bd7d8755efcd7b0f0a7f77c0a516b035db6e41acb45235774b42f08bb1190dfe99c69998; Path=/; HttpOnly;' ],
'strict-transport-security': 'max-age=31536000; includeSubDomains; preload;',
vary: 'Accept-Encoding',
'x-csrf-token': 'Required',
'x-frame-options': 'SAMEORIGIN',
'x-request-id': '82dffecf-5f64-4a40-4d73-d173f8b5d96f',
'x-vcap-request-id': '82dffecf-5f64-4a40-4d73-d173f8b5d96f',
connection: 'close' },
rawHeaders:
[ 'Content-Length',
'28',
'Content-Type',
'text/plain; charset=utf-8',
'Date',
'Tue, 23 Feb 2021 21:29:55 GMT',
'Sap-Perf-Fesrec',
'20749.000000',
'Sap-Processing-Info',
'ODataBEP=,crp=,RAL=,st=,MedCacheHub=,codeployed=X,softstate=',
'Sap-Server',
'true',
'Set-Cookie',
'ARBE=b495e4ffe60015994d0fa318954b96f235a5706c18ad8aeca366ae15c23680b8d3e794ee3403ca4a22e6611b885ec55cb13394db382a9e54f5c6a710ab25525d9fc6e186192c55114450b0be5d24c4dcaef6521c562edb3aa942eafac59abc85391cdb0966817bc55b4a2cbf766f69d732c973817bd3088b6a8f4b4ac1ee95f2e1d5d1f1963d0f0fe74603e42030843d875337c75d0bac4854b8e1354aea20805a75a839cbfc52baa810ff58df6937e7eb5dbf99f35cc2c103eb2495caad5f1b96b05374d9985999d350284dbdc641f6196ca26a444f602f93a4162894520a975df182428e3c17fc5f434842588c6fd326833b9c72e11a0d4c4d81ea9e77f1a196c250d801b14e0d5c8e4e4c932f02ca47989bfd95cedf8b89adc9e61231321649793401716fac36efd05825e76b121c973dbf021e1d2922b389eb34215187edadb4da447d1a542f43ed6f04bb850798d983cc9cd636d998c029a886c0172680dbd746d6f2b5d917e0382b19b854bf3c262d1ec3be4c13974283edd92309e9c2010e7985abe20334e440a935aef1430906afc681b94abd8331f329eb3d95f60e68f459550f53395113ffb75104167746ee783484b1eecf6410a0d7ff32e3fc3b3e24435bbbea79d5a716cd868114fcdcbbfa56c9c08f550512332efd97e0b9a7aa081c9284a9702f6433f0ea3e6f643dfaa0c6ade9e7a157492bed1985dbdcb5f780cd4f7fbbce6429c1c4cd444fcad7d4f1efa056c0eb5ecf62ec686d3f4c4e95c83704acf9b28e098a65f1c3dea5c008674868611bd0391659c1bdbecd6790801649e4898814035d7a84b624463e84910d335d52435bc6c2c72de4bd7d8755efcd7b0f0a7f77c0a516b035db6e41acb45235774b42f08bb1190dfe99c69998; Path=/; HttpOnly;',
'Strict-Transport-Security',
'max-age=31536000; includeSubDomains; preload;',
'Vary',
'Accept-Encoding',
'X-Csrf-Token',
'Required',
'X-Frame-Options',
'SAMEORIGIN',
'X-Request-Id',
'82dffecf-5f64-4a40-4d73-d173f8b5d96f',
'X-Vcap-Request-Id',
'82dffecf-5f64-4a40-4d73-d173f8b5d96f',
'Connection',
'close' ],
trailers: {},
rawTrailers: [],
aborted: false,
upgrade: false,
url: '',
method: null,
statusCode: 403,
statusMessage: 'Forbidden',
client:
Socket {
connecting: false,
_hadError: false,
_handle:
TCP {
reading: true,
onread: [Function: onStreamRead],
onconnection: null,
[Symbol(owner)]: [Circular] },
_parent: null,
_host: null,
_readableState:
ReadableState {
objectMode: false,
highWaterMark: 16384,
buffer: BufferList { head: null, tail: null, length: 0 },
length: 0,
pipes: null,
pipesCount: 0,
flowing: true,
ended: false,
endEmitted: false,
reading: true,
sync: false,
needReadable: true,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
paused: false,
emitClose: false,
autoDestroy: false,
destroyed: false,
defaultEncoding: 'utf8',
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null },
readable: true,
_events:
[Object: null prototype] {
end: [Function: onReadableStreamEnd],
free: { [Function: bound onceWrapper] listener: [Function] },
drain: [Function: ondrain],
error: [Function: socketErrorListener],
close: [Function: socketCloseListener],
finish:
{ [Function: bound onceWrapper] listener: [Function: destroy] } },
_eventsCount: 6,
_maxListeners: undefined,
_writableState:
WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: true,
needDrain: false,
ending: true,
ended: true,
finished: false,
destroyed: false,
decodeStrings: false,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: false,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 1,
prefinished: false,
errorEmitted: false,
emitClose: false,
autoDestroy: false,
bufferedRequestCount: 0,
corkedRequestsFree:
{ next:
{ next: null,
entry: null,
finish: [Function: bound onCorkedFinish] },
entry: null,
finish: [Function: bound onCorkedFinish] } },
writable: false,
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: null,
_server: null,
parser: null,
_httpMessage: [Circular],
[Symbol(asyncId)]: 402,
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0 },
_consuming: false,
_dumped: false,
req: [Circular],
responseUrl:
'http://businesspartner.dest/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner(BusinessPartner=%27HARUT%27)',
redirects: [] },
aborted: undefined,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
_redirectable:
Writable {
_writableState:
WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: false,
needDrain: false,
ending: false,
ended: false,
finished: false,
destroyed: false,
decodeStrings: true,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: true,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 0,
prefinished: false,
errorEmitted: false,
emitClose: true,
autoDestroy: false,
bufferedRequestCount: 0,
corkedRequestsFree:
{ next: null,
entry: null,
finish: [Function: bound onCorkedFinish] } },
writable: true,
_events:
[Object: null prototype] {
response: [Function: handleResponse],
error: [Function: handleRequestError] },
_eventsCount: 2,
_maxListeners: undefined,
_options:
{ maxRedirects: 21,
maxBodyLength: 10485760,
protocol: 'http:',
path:
'/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner(BusinessPartner=%27HARUT%27)',
method: 'PATCH',
headers:
{ Accept: 'application/json',
'Content-Type': 'application/json',
'User-Agent': 'axios/0.21.1',
'Content-Length': 48 },
agent:
HttpProxyAgent {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
timeout: null,
maxFreeSockets: 1,
maxSockets: 1,
maxTotalSockets: Infinity,
sockets: {},
freeSockets: {},
requests: {},
options: {},
secureProxy: false,
proxy:
{ protocol: 'http:',
slashes: true,
auth: null,
host: '127.0.0.1',
port: 8887,
hostname: '127.0.0.1',
hash: null,
search: null,
query: null,
href: 'http://127.0.0.1:8887/' },
promisifiedCallback: [Function: callback] },
agents:
{ http:
HttpProxyAgent {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
timeout: null,
maxFreeSockets: 1,
maxSockets: 1,
maxTotalSockets: Infinity,
sockets: {},
freeSockets: {},
requests: {},
options: {},
secureProxy: false,
proxy:
{ protocol: 'http:',
slashes: true,
auth: null,
host: '127.0.0.1',
port: 8887,
hostname: '127.0.0.1',
hash: null,
search: null,
query: null,
href: 'http://127.0.0.1:8887/' },
promisifiedCallback: [Function: callback] },
https:
Agent {
_events: [Object: null prototype] { free: [Function] },
_eventsCount: 1,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: { path: null },
requests: {},
sockets: {},
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
maxCachedSessions: 100,
_sessionCache: { map: {}, list: [] } } },
auth: undefined,
hostname: 'businesspartner.dest',
port: null,
nativeProtocols:
{ 'http:':
{ _connectionListener: [Function: connectionListener],
METHODS:
[ 'ACL',
'BIND',
'CHECKOUT',
'CONNECT',
'COPY',
'DELETE',
'GET',
'HEAD',
'LINK',
'LOCK',
'M-SEARCH',
'MERGE',
'MKACTIVITY',
'MKCALENDAR',
'MKCOL',
'MOVE',
'NOTIFY',
'OPTIONS',
'PATCH',
'POST',
'PROPFIND',
'PROPPATCH',
'PURGE',
'PUT',
'REBIND',
'REPORT',
'SEARCH',
'SOURCE',
'SUBSCRIBE',
'TRACE',
'UNBIND',
'UNLINK',
'UNLOCK',
'UNSUBSCRIBE' ],
STATUS_CODES:
{ '100': 'Continue',
'101': 'Switching Protocols',
'102': 'Processing',
'103': 'Early Hints',
'200': 'OK',
'201': 'Created',
'202': 'Accepted',
'203': 'Non-Authoritative Information',
'204': 'No Content',
'205': 'Reset Content',
'206': 'Partial Content',
'207': 'Multi-Status',
'208': 'Already Reported',
'226': 'IM Used',
'300': 'Multiple Choices',
'301': 'Moved Permanently',
'302': 'Found',
'303': 'See Other',
'304': 'Not Modified',
'305': 'Use Proxy',
'307': 'Temporary Redirect',
'308': 'Permanent Redirect',
'400': 'Bad Request',
'401': 'Unauthorized',
'402': 'Payment Required',
'403': 'Forbidden',
'404': 'Not Found',
'405': 'Method Not Allowed',
'406': 'Not Acceptable',
'407': 'Proxy Authentication Required',
'408': 'Request Timeout',
'409': 'Conflict',
'410': 'Gone',
'411': 'Length Required',
'412': 'Precondition Failed',
'413': 'Payload Too Large',
'414': 'URI Too Long',
'415': 'Unsupported Media Type',
'416': 'Range Not Satisfiable',
'417': 'Expectation Failed',
'418': 'I\'m a Teapot',
'421': 'Misdirected Request',
'422': 'Unprocessable Entity',
'423': 'Locked',
'424': 'Failed Dependency',
'425': 'Unordered Collection',
'426': 'Upgrade Required',
'428': 'Precondition Required',
'429': 'Too Many Requests',
'431': 'Request Header Fields Too Large',
'451': 'Unavailable For Legal Reasons',
'500': 'Internal Server Error',
'501': 'Not Implemented',
'502': 'Bad Gateway',
'503': 'Service Unavailable',
'504': 'Gateway Timeout',
'505': 'HTTP Version Not Supported',
'506': 'Variant Also Negotiates',
'507': 'Insufficient Storage',
'508': 'Loop Detected',
'509': 'Bandwidth Limit Exceeded',
'510': 'Not Extended',
'511': 'Network Authentication Required' },
Agent:
{ [Function: Agent]
super_:
{ [Function: EventEmitter]
once: [Function: once],
EventEmitter: [Circular],
usingDomains: false,
defaultMaxListeners: [Getter/Setter],
init: [Function],
listenerCount: [Function] },
defaultMaxSockets: Infinity },
ClientRequest:
{ [Function: ClientRequest]
super_:
{ [Function: OutgoingMessage]
super_:
{ [Function: Stream]
super_: [Function],
Readable: [Function],
Writable: [Function],
Duplex: [Function],
Transform: [Function],
PassThrough: [Function],
pipeline: [Function: pipeline],
finished: [Function: eos],
Stream: [Circular],
_isUint8Array: [Function: isUint8Array],
_uint8ArrayToBuffer: [Function: _uint8ArrayToBuffer] } } },
IncomingMessage:
{ [Function: IncomingMessage]
super_:
{ [Function: Readable]
ReadableState: [Function: ReadableState],
super_:
{ [Function: Stream]
super_: [Function],
Readable: [Circular],
Writable: [Function],
Duplex: [Function],
Transform: [Function],
PassThrough: [Function],
pipeline: [Function: pipeline],
finished: [Function: eos],
Stream: [Circular],
_isUint8Array: [Function: isUint8Array],
_uint8ArrayToBuffer: [Function: _uint8ArrayToBuffer] },
_fromList: [Function: fromList],
from: [Function] } },
OutgoingMessage:
{ [Function: OutgoingMessage]
super_:
{ [Function: Stream]
super_:
{ [Function: EventEmitter]
once: [Function: once],
EventEmitter: [Circular],
usingDomains: false,
defaultMaxListeners: [Getter/Setter],
init: [Function],
listenerCount: [Function] },
Readable:
{ [Function: Readable]
ReadableState: [Function: ReadableState],
super_: [Circular],
_fromList: [Function: fromList],
from: [Function] },
Writable:
{ [Function: Writable] WritableState: [Function: WritableState], super_: [Circular] },
Duplex: { [Function: Duplex] super_: [Function] },
Transform: { [Function: Transform] super_: [Function] },
PassThrough: { [Function: PassThrough] super_: [Function] },
pipeline: [Function: pipeline],
finished: [Function: eos],
Stream: [Circular],
_isUint8Array: [Function: isUint8Array],
_uint8ArrayToBuffer: [Function: _uint8ArrayToBuffer] } },
Server:
{ [Function: Server]
super_:
{ [Function: Server]
super_:
{ [Function: EventEmitter]
once: [Function: once],
EventEmitter: [Circular],
usingDomains: false,
defaultMaxListeners: [Getter/Setter],
init: [Function],
listenerCount: [Function] } } },
ServerResponse:
{ [Function: ServerResponse]
super_:
{ [Function: OutgoingMessage]
super_:
{ [Function: Stream]
super_: [Function],
Readable: [Function],
Writable: [Function],
Duplex: [Function],
Transform: [Function],
PassThrough: [Function],
pipeline: [Function: pipeline],
finished: [Function: eos],
Stream: [Circular],
_isUint8Array: [Function: isUint8Array],
_uint8ArrayToBuffer: [Function: _uint8ArrayToBuffer] } } },
createServer: [Function: createServer],
get: [Function: get],
request: [Function: request],
maxHeaderSize: [Getter],
globalAgent: [Getter/Setter] },
'https:':
{ Agent:
{ [Function: Agent]
super_:
{ [Function: Agent]
super_:
{ [Function: EventEmitter]
once: [Function: once],
EventEmitter: [Circular],
usingDomains: false,
defaultMaxListeners: [Getter/Setter],
init: [Function],
listenerCount: [Function] },
defaultMaxSockets: Infinity } },
globalAgent:
Agent {
_events: [Object: null prototype] { free: [Function] },
_eventsCount: 1,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: { path: null },
requests: {},
sockets: {},
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
maxCachedSessions: 100,
_sessionCache: { map: {}, list: [] } },
Server:
{ [Function: Server]
super_:
{ [Function: Server] super_: { [Function: Server] super_: [Function] } } },
createServer: [Function: createServer],
get: [Function: get],
request: [Function: request] } },
pathname:
'/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner(BusinessPartner=%27HARUT%27)' },
_ended: true,
_ending: true,
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 48,
_requestBodyBuffers: [],
_onNativeResponse: [Function],
_currentRequest: [Circular],
_currentUrl:
'http://businesspartner.dest/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner(BusinessPartner=%27HARUT%27)' },
[Symbol(isCorked)]: false,
[Symbol(outHeadersKey)]:
[Object: null prototype] {
accept: [ 'Accept', 'application/json' ],
'content-type': [ 'Content-Type', 'application/json' ],
'user-agent': [ 'User-Agent', 'axios/0.21.1' ],
'content-length': [ 'Content-Length', 48 ],
host: [ 'Host', 'businesspartner.dest' ] } },
data: 'CSRF token validation failed' },
isAxiosError: true,
toJSON: [Function: toJSON] },
name: 'ErrorWithCause' },
name: 'ErrorWithCause' }
Log output in CF:
2021-02-23T21:33:08.16+0000 [APP/PROC/WEB/0] ERR [cds] - GET /test/insertBupa()
2021-02-23T21:33:08.17+0000 [APP/PROC/WEB/0] OUT {"message":"Attempting to retrieve destination from environment variable.","level":"info","custom_fields":{"package":"core","messageContext":"env-destination-accessor"},"logger":"sap-cloud-sdk-logger","timestamp":"2021-02-23T21:33:08.172Z","msg":"Attempting to retrieve destination from environment variable.","written_ts":1614115988172,"written_at":"2021-02-23T21:33:08.172Z"}
2021-02-23T21:33:08.17+0000 [APP/PROC/WEB/0] OUT {"message":"No environment variable set.","level":"info","custom_fields":{"package":"core","messageContext":"env-destination-accessor"},"logger":"sap-cloud-sdk-logger","timestamp":"2021-02-23T21:33:08.172Z","msg":"No environment variable set.","written_ts":1614115988172,"written_at":"2021-02-23T21:33:08.172Z"}
2021-02-23T21:33:08.17+0000 [APP/PROC/WEB/0] OUT {"message":"Attempting to retrieve destination from service binding.","level":"info","custom_fields":{"package":"core","messageContext":"destination-accessor-vcap"},"logger":"sap-cloud-sdk-logger","timestamp":"2021-02-23T21:33:08.172Z","msg":"Attempting to retrieve destination from service binding.","written_ts":1614115988172,"written_at":"2021-02-23T21:33:08.172Z"}
2021-02-23T21:33:08.17+0000 [APP/PROC/WEB/0] OUT {"message":"Could not retrieve destination from service binding. If you are not using SAP Extension Factory, this information probably does not concern you. Unable to find a service binding for given name \"BusinessPartner\"! Found the following bindings: BusinessPartnerVerification-dest, BusinessPartnerVerification-cs, test-uaa.\n ","level":"info","custom_fields":{"package":"core","messageContext":"destination-accessor-vcap"},"logger":"sap-cloud-sdk-logger","timestamp":"2021-02-23T21:33:08.173Z","msg":"Could not retrieve destination from service binding. If you are not using SAP Extension Factory, this information probably does not concern you. Unable to find a service binding for given name \"BusinessPartner\"! Found the following bindings: BusinessPartnerVerification-dest, BusinessPartnerVerification-cs, test-uaa.\n ","written_ts":1614115988173,"written_at":"2021-02-23T21:33:08.173Z"}
2021-02-23T21:33:08.17+0000 [APP/PROC/WEB/0] OUT {"message":"Attempting to retrieve destination from destination service.","level":"info","custom_fields":{"package":"core","messageContext":"destination-accessor-service"},"logger":"sap-cloud-sdk-logger","timestamp":"2021-02-23T21:33:08.173Z","msg":"Attempting to retrieve destination from destination service.","written_ts":1614115988173,"written_at":"2021-02-23T21:33:08.173Z"}
2021-02-23T21:33:08.17+0000 [APP/PROC/WEB/0] OUT {"message":"Unable to match a specific XSUAA service instance to the given JWT. The following XSUAA instances are bound: test!t75418. The following one will be selected: test!t75418. This might produce errors in other parts of the system!","level":"warn","custom_fields":{"package":"core","messageContext":"environment-accessor"},"logger":"sap-cloud-sdk-logger","timestamp":"2021-02-23T21:33:08.173Z","msg":"Unable to match a specific XSUAA service instance to the given JWT. The following XSUAA instances are bound: test!t75418. The following one will be selected: test!t75418. This might produce errors in other parts of the system!","written_ts":1614115988173,"written_at":"2021-02-23T21:33:08.173Z"}
2021-02-23T21:33:08.20+0000 [APP/PROC/WEB/0] OUT {"message":"Successfully retrieved destination from destination service.","level":"info","custom_fields":{"package":"core","messageContext":"destination-accessor-service"},"logger":"sap-cloud-sdk-logger","timestamp":"2021-02-23T21:33:08.206Z","msg":"Successfully retrieved destination from destination service.","written_ts":1614115988206,"written_at":"2021-02-23T21:33:08.206Z"}
2021-02-23T21:33:08.20+0000 [APP/PROC/WEB/0] OUT {"message":"OnPrem destination proxy settings from connectivity service will be used.","level":"info","custom_fields":{"package":"core","messageContext":"proxy-util"},"logger":"sap-cloud-sdk-logger","timestamp":"2021-02-23T21:33:08.206Z","msg":"OnPrem destination proxy settings from connectivity service will be used.","written_ts":1614115988206,"written_at":"2021-02-23T21:33:08.206Z"}
2021-02-23T21:33:08.20+0000 [APP/PROC/WEB/0] OUT {"message":"Unable to match a specific XSUAA service instance to the given JWT. The following XSUAA instances are bound: test!t75418. The following one will be selected: test!t75418. This might produce errors in other parts of the system!","level":"warn","custom_fields":{"package":"core","messageContext":"environment-accessor"},"logger":"sap-cloud-sdk-logger","timestamp":"2021-02-23T21:33:08.206Z","msg":"Unable to match a specific XSUAA service instance to the given JWT. The following XSUAA instances are bound: test!t75418. The following one will be selected: test!t75418. This might produce errors in other parts of the system!","written_ts":1614115988206,"written_at":"2021-02-23T21:33:08.206Z"}
2021-02-23T21:33:08.20+0000 [APP/PROC/WEB/0] OUT {"message":"Unable to create \"SAP-Connectivity-Authentication\" header: no JWT found on the current request.\n Continuing without header. Connecting to on-premise systems may not be possible.","level":"warn","custom_fields":{"package":"core","messageContext":"connectivity-service"},"logger":"sap-cloud-sdk-logger","timestamp":"2021-02-23T21:33:08.206Z","msg":"Unable to create \"SAP-Connectivity-Authentication\" header: no JWT found on the current request.\n Continuing without header. Connecting to on-premise systems may not be possible.","written_ts":1614115988206,"written_at":"2021-02-23T21:33:08.206Z"}
2021-02-23T21:33:08.20+0000 [APP/PROC/WEB/0] OUT {"message":"The custom headers are provided with the keys: x-csrf-token,authorization,Proxy-Authorization,sap-client. These keys will overwrite the headers created by the SDK.","level":"warn","custom_fields":{"package":"core","messageContext":"http-client"},"logger":"sap-cloud-sdk-logger","timestamp":"2021-02-23T21:33:08.208Z","msg":"The custom headers are provided with the keys: x-csrf-token,authorization,Proxy-Authorization,sap-client. These keys will overwrite the headers created by the SDK.","written_ts":1614115988208,"written_at":"2021-02-23T21:33:08.208Z"}
2021-02-23T21:33:08.20+0000 [APP/PROC/WEB/0] OUT {"message":"Found custom authorization headers. The given destination also provides authorization headers. This might be unintended. The custom headers from the request config will be used.","level":"warn","custom_fields":{"package":"core","messageContext":"authorization-header"},"logger":"sap-cloud-sdk-logger","timestamp":"2021-02-23T21:33:08.208Z","msg":"Found custom authorization headers. The given destination also provides authorization headers. This might be unintended. The custom headers from the request config will be used.","written_ts":1614115988208,"written_at":"2021-02-23T21:33:08.208Z"}
2021-02-23T21:33:08.42+0000 [APP/PROC/WEB/0] OUT {"message":"The custom headers are provided with the keys: authorization,Proxy-Authorization,sap-client,x-csrf-token,cookie,content-type,accept. These keys will overwrite the headers created by the SDK.","level":"warn","custom_fields":{"package":"core","messageContext":"http-client"},"logger":"sap-cloud-sdk-logger","timestamp":"2021-02-23T21:33:08.420Z","msg":"The custom headers are provided with the keys: authorization,Proxy-Authorization,sap-client,x-csrf-token,cookie,content-type,accept. These keys will overwrite the headers created by the SDK.","written_ts":1614115988420,"written_at":"2021-02-23T21:33:08.420Z"}
2021-02-23T21:33:08.42+0000 [APP/PROC/WEB/0] OUT {"message":"Found custom authorization headers. The given destination also provides authorization headers. This might be unintended. The custom headers from the request config will be used.","level":"warn","custom_fields":{"package":"core","messageContext":"authorization-header"},"logger":"sap-cloud-sdk-logger","timestamp":"2021-02-23T21:33:08.420Z","msg":"Found custom authorization headers. The given destination also provides authorization headers. This might be unintended. The custom headers from the request config will be used.","written_ts":1614115988420,"written_at":"2021-02-23T21:33:08.420Z"}
2021-02-23T21:33:13.72+0000 [APP/PROC/WEB/0] OUT βββββββββββββββββββ¬βββββββββββββββ
2021-02-23T21:33:13.72+0000 [APP/PROC/WEB/0] OUT β (index) β Values β
2021-02-23T21:33:13.72+0000 [APP/PROC/WEB/0] OUT βββββββββββββββββββΌβββββββββββββββ€
2021-02-23T21:33:13.72+0000 [APP/PROC/WEB/0] OUT β businessPartner β 'HARUT' β
2021-02-23T21:33:13.72+0000 [APP/PROC/WEB/0] OUT β firstName β 'First Name' β
2021-02-23T21:33:13.72+0000 [APP/PROC/WEB/0] OUT β lastName β 'LastName' β
2021-02-23T21:33:13.72+0000 [APP/PROC/WEB/0] OUT βββββββββββββββββββ΄βββββββββββββββ
2021-02-23T21:33:13.72+0000 [RTR/20] OUT tfe-dev-dev-test-srv.cfapps.eu10.hana.ondemand.com - [2021-02-23T21:33:08.159080370Z] "GET /test/insertBupa() HTTP/1.1" 204 0 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.152 Safari/537.36" "-" "10.0.73.192:61235" x_forwarded_for:"-" x_forwarded_proto:"https" vcap_request_id:"0396b65e-5f73-4a6c-6584-9c517c775eec" response_time:5.563391 gorouter_time:0.000129 app_id:"c6d4999b-a9c6-4fd8-b07e-fa31250d588e" app_index:"0" x_cf_routererror:"-" x_correlationid:"-" tenantid:"-" sap_passport:"-" x_scp_request_id:"10cb1a4a-d6b0-450b-bcb9-e68cbd243342-6035748D-41FA43" x_cf_app_instance:"-" x_b3_traceid:"f9dec6be9bbd9e67" x_b3_spanid:"f9dec6be9bbd9e67" x_b3_parentspanid:"-" b3:"f9dec6be9bbd9e67-f9dec6be9bbd9e67"
2021-02-23T21:33:13.72+0000 [RTR/20] OUT
Additional context
Destination configuration:
Issue Analytics
- State:
- Created 3 years ago
- Comments:14 (14 by maintainers)
works - as discussed. Needed to remove the @sap-cloud-sdk/core package coming from the vdm package (which doesnβt include the canary changes)
Hello @maxstreifeneder,
I made a little test in our BAS test application and for me the fetching of the CSRF token worked:
Since fetching the CSRF token is the first thing done towards the S/4 system are you sure your connection to the backend works? Could you perhaps make a
getAll().top(5)
test to see if you get some data? If this is also not working I assume that something is wrong with your connectivity setup.Note that you have to set the
destinations
array in the SDK as described here: https://sap.github.io/cloud-sdk/docs/js/guides/bas-external-systemBest Frank
P.S.:Note that the PrincipalPropgation section is potentially wrong so stick to basic.