SAP / cloud-sdk-js

Use the SAP Cloud SDK for JavaScript / TypeScript to reduce development effort when building applications on SAP Business Technology Platform that communicate with SAP solutions and services such as SAP S/4HANA Cloud, SAP SuccessFactors, and many others.
Apache License 2.0
161 stars 55 forks source link

getDestinationFromDestinationService keeps return the same SAMLAssertion if useCache=true and resulting 401-Unauthorized error #4851

Closed yaosheng79 closed 1 week ago

yaosheng79 commented 1 month ago

Describe the bug The customer reported that in SAP BuildApps, oData requests sent to S/4HANA Cloud only succeed once every few minutes. After investigating, I found that this issue is caused by the cloud SDK.

If invoke getDestinationFromDestinationService() with the useCache=true. Within every 5 minutes, authTokens always return the same SAML Assertion, but SAML Assertions should be one-time use only. This results in backend calls succeeding only once every 5 minutes, while all other requests return 401 - Unauthorized errors.

To Reproduce Steps to reproduce the behavior:

  1. Create a destination using SAMLAssertion authentication type
  2. call getDestinationFromDestinationService with below code snippet
    const destination = await getDestinationFromDestinationService({
    destinationName: destName,
    jwt: userJwtToken,
    iasToXsuaaTokenExchange: true,
    useCache: true,
    });
  3. Execute repeatedly and check authTokens[0].value.

You will find that within 5 minutes, the same SAML Assertion is returned regardless of how many times you call, and only after 5 minutes does it change to a new one.

Expected behavior Each returned SAML Assertion should be different every time.

Screenshots If applicable, add screenshots to help explain your problem.

Used Versions:

Code Examples If applicable, add code snippets as examples to help explain your problem. Please remove sensitive information.

Log file If applicable, add your log file or related error message. Again, please remove your sensitive information.

Impact / Priority

Affected development phase: e.g. Getting Started, Development, Release, Production

Impact: e.g. No Impact, Inconvenience, Impaired, Blocked

Timeline: e.g. Go-Live is in 12 weeks.

Additional context Add any other context about the problem here.

yaosheng79 commented 1 month ago

BTW, if I directly access the REST API of Destination Service to obtain the configuration of the same destination, like below:

const jwtToken = await _doTokenExchange(userJwtToken);
const destServiceUrl = `${DESTINATION_CREDENTIALS.uri}/destination-configuration/v1/destinations/${destName}`;
const options = {
    headers: { Authorization: 'Bearer ' + jwtToken}
};
const response = await fetch(destServiceUrl, options);
const destination = await response.json();

each call returns a different SAML Assertion, which is exactly the expected behaviour.

So I suspect this issue should be caused by the caching mechanism of the @sap-cloud-sdk/connectivity.

tomfrenken commented 1 month ago

Hey @yaosheng79,

thanks for reporting this bug, I will investigate the cause and let you know once we've implemented a fix.

deekshas8 commented 1 week ago

Hi @yaosheng79,

This is the expected behavior. The caching strategy of the SDK is explained here. As you have set useCache: true and the expiration time of the SAML 2.0 auth token is undefined, the default expiration time of 5mins is then taken into account. Since each call to the destination service returns a different SAML Assertion, in your case you don't need to cache the destination.