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
162 stars 55 forks source link

getDestination throws error after multitenant broker request #4932

Open maxpfab opened 3 weeks ago

maxpfab commented 3 weeks ago

Hi Experts,

I have a problem with the getDestination Method of the package @sap-cloud-sdk/connectivity version 3.18.0. Every time when i try to call my endpoint of my CAP API with my service broker user, I get the following issue: 2024-08-14T13:15:51.31+0000 [APP/PROC/WEB/0] ERR [cds|317255b8-e617-4762-b58d-73c78ae07d8f] - Error: Could not find XSUAA service binding matching the token.

The construct is the following:

So what I want to achieve is to read the subscriber subaccount destination details with the technical user directly on the request. On the version 3.15.0 it is still working. Keep in mind that this is a multitenant scenario.

Steps to reproduce the behavior:

  1. Create Service Broker on Subscriber Sub Account
  2. Read Client ID & Creedentails
  3. Execute http script which gets JWT-token first
  4. Execute http script with token request on service

I Attach the files for the sourcecode and also for the error which will occure.

Application Versions:

Impact / Priority Only wanted to let you know that it is not working as expected. It will be a problem in the future because if it is not fixed I need to stay on the version 3.15.0 in each of my implementations. So when I want to publish a new version I would be happy if it is fixed.

deekshas8 commented 3 weeks ago

Hi @maxpfab ,

The previous implementation (in v3.15.0) was actually a bug that we fixed in the later versions. In a multi-tenant scenario, when a user token is passed to getDestination, client_id and audience from the token are used to determine the bound XSUAA service instance, that is then used to verify this token.

If you get your JWT from an approuter, can you make sure that its using the same XSUAA instance that is bound to your application? You should see more info in the debug logs. You can turn them on by calling setGlobalLogLevel('debug') (imported from @sap-cloud-sdk/util) as the first line in your code.

I would also recommend our debugging guide to get more insights into why the error occurs.

maxpfab commented 3 weeks ago

Hello @deekshas8,

What I read from this is that I still pass a JWT token, in my case a service broker token, and this is then resolved and gets the destinations from the XSUAA instance, right?

Is there not somehow an automatic procedure that I no longer have to provide the token for such a technichal user request? I already specify in the getDestination function that it should be read from the subscriber(alwaysSubscriber) subaccount from which the JWT token originates when the service is called.

Unfortunately, I cannot bind the JWT from the AppRouter instance, as this is a second service API, which should not communicate with a normal user. So only technical access should be possible via the service broker.

Thank you for you quick response :)

Regards, Max

deekshas8 commented 2 weeks ago

Hi @maxpfab ,

and this is then resolved and gets the destinations from the XSUAA instance, right?

The passed JWT is first verified by the XSUAA service instance that is bound to your application. The JWT's client_id and audience are used to determine this instance. (This is the step where you get the error). Once the JWT is verified, the same XSUAA instance is used to obtain a client credentials token for the destination service, which is then used to fetch the destinations.

Is there not somehow an automatic procedure that I no longer have to provide the token for such a technichal user request?

No, in a multi-tenant app, a JWT is mandatory. Our documented here explains the setup required. I also found this blog that states some limitations with using the service broker approach. Maybe this gives some insights to your issue.

maxpfab commented 2 weeks ago

Hi @deekshas8 ,

But if I have a second XSUAA instance with the plan broker, then this should also receive the JWT token from the subaccount. And because I only call the service API, the token should be valid.

Unfortunately, this technical user is there to read data from the service. So it is not possible.

How can I then achieve what I need with technical access? Is there any other possibility here?

tomfrenken commented 2 weeks ago

Hi @maxpfab,

generally speaking, binding the same XSUAA instance to your app and approuter is a hard requirement, otherwise, no matter your setup, the JWT validation will always fail.

Please also be more precise in describing what exact setup you currently have, as this is very hard to grasp.

Could you please outline, which application has bound which services to them (and if they are using the same instance of it) and is trying to connect to which service?

You can orient your description based on this image.

maxpfab commented 1 week ago

Hi @tomfrenken,

What do you mean by saying that I should always link all XSUAA instances to the Approuter?

Here is a short description of my service: It was implemented in SAP CAP Service, which exposes a service that uses an API to pack data from a third party system into an OData construct and return it. Since every customer has different data, the multitenant approach was used here. To avoid having to create a Cloud Foundry environment in every subscriber subaccount, there are two XSUAA instances. One XSUAA instance is of the type application which is for normal service access and then a service broker is registered which uses an XUSAA instance of the type broker. The Service Broker is used for the technical access.

What I understand from the statement above is that it should be enough to bind the XSUAA instance with type service broker to the approuter?

My app is based on the SAP repo https://github.com/SAP-samples/btp-cap-multitenant-saas/blob/main/deploy/cf/mta.yaml, the only difference is that my broker goes directly to the service and has not implemented its own service for it.

Regards, Max

maxpfab commented 3 days ago

Hi @tomfrenken,

is there any updated based on my problem?

What I don't understand exactly, I have the service xsuaa instance which can access the destination service without problems, but the token of the broker which have the same subaccountid and issuer in the jwt token can't access the destinations.

If this does not work, I would need a way to make this technical access anyway. Is that somehow possible?

Regards, Max