From 4ec8fef23e0712aa065928fc1532d8028cb78976 Mon Sep 17 00:00:00 2001 From: D051920 Date: Thu, 28 May 2026 10:19:16 +0200 Subject: [PATCH 1/4] Add Node.js part to Outbound Authentication --- guides/security/remote-authentication.md | 127 +++++++++++++++++++++-- 1 file changed, 117 insertions(+), 10 deletions(-) diff --git a/guides/security/remote-authentication.md b/guides/security/remote-authentication.md index 1f3141b0a..bbe3e5a8b 100644 --- a/guides/security/remote-authentication.md +++ b/guides/security/remote-authentication.md @@ -59,6 +59,7 @@ Technically, **they share the same identity instance, which allows direct token ![Co-located services](./assets/co-located-services.drawio.svg){width="450px" } [Learn more about how to configure co-located services in CAP Java](/java/cqn-services/remote-services#binding-to-a-service-with-shared-identity) {.learn-more} +[Learn more about how to configure remote services in CAP Node.js](/node.js/remote-services) {.learn-more} You can test CAP's built-in support for co-located services in practice by modifying the [`xflights-java`](https://github.com/capire/xflights-java/tree/main) and [`xtravels-java`](https://github.com/capire/xtravels-java/tree/main) sample applications. `xflights-java` acts as a master data provider exposing basic flight data in service [`sap.capire.flights.data`](https://github.com/capire/xflights-java/blob/6fc7c665c63bb6d73e28c11b391b1ba965b8772c/srv/data-service.cds#L24) via different protocols. @@ -88,7 +89,7 @@ As client, `xtravels-srv` first needs a valid configuration for the remote servi ::: code-group -```yaml [/srv/src/main/resources/application.yaml] +```yaml [Java: application.yaml] --- spring: config.activate.on-profile: cloud @@ -105,26 +106,60 @@ cds: options: url: https:// ``` + +```json [Node.js: package.json] +{ + "cds": { + "requires": { + "xflights": { + "kind": "hcql", + "model": "sap.capire.flights.data", + "[production]": { + "credentials": { + "url": "https:///hcql", + "forwardAuthToken": true + } + } + } + } + } +} +``` ::: -The `type` property activates the protocol for exchanging business data and must be offered by the provider [CDS service](https://github.com/capire/xflights-java/blob/6fc7c665c63bb6d73e28c11b391b1ba965b8772c/srv/data-service.cds#L24). +The `type` (Java) or `kind` (Node.js) property activates the protocol for exchanging business data and must be offered by the provider [CDS service](https://github.com/capire/xflights-java/blob/6fc7c665c63bb6d73e28c11b391b1ba965b8772c/srv/data-service.cds#L24). The `model` property needs to match the fully qualified name of the CDS service from the imported model. You can find CDS service definition of `sap.capire.flights.data` in file `target/cds/capire/xflight-data/service.cds` resolved during CDS build step. -The `binding.name` needs to point to the shared identity instance and `options.url` together with `http.suffix` provides the required location of the remote service endpoint. -Finally, `onBehalfOf: systemUser` specifies that the remote call is invoked on behalf of a technical user in context of the tenant. + +In Java, the `binding.name` needs to point to the shared identity instance and `options.url` together with `http.suffix` provides the required location of the remote service endpoint. +In Node.js, `credentials.url` provides the full endpoint URL, and `forwardAuthToken: true` enables direct forwarding of the incoming JWT token to the provider service. + +Finally, `onBehalfOf: systemUser` (Java) specifies that the remote call is invoked on behalf of a technical user in context of the tenant. ::: tip On behalf of `systemUser` works both in pure single tenant and in pure multitenant scenarios. If you are consuming a single tenant service from within a multitenant application choose on behalf of `systemUserProvider`. ::: +::: tip Node.js token forwarding +In Node.js, `forwardAuthToken: true` forwards the incoming request's JWT token directly to the provider. +This is suitable for co-located services that share the same identity instance, as the token is already valid for the provider. +::: + Now you are ready to deploy the application with -```sh +::: code-group +```sh [Java] cd ./xtravels_java cds up ``` +```sh [Node.js] +cd ./xtravels +cds up +``` +::: + ❗Note that CF application `xtravels-srv` will not start successfully as long as `xflights` is not deployed yet (step 3). ::: tip @@ -172,11 +207,18 @@ resources: Finally, deploy and start the application with -```sh +::: code-group +```sh [Java] cd ./xflights_java cds up ``` +```sh [Node.js] +cd ./xflights +cds up +``` +::: + #### 4. Verify the deployment { #verify } First, you can check the overall deployment status at the CF CLI level. Specifically, the application services must be started successfully and the shared identity instance must be verified. @@ -310,12 +352,14 @@ Instead of using the same role, expose dedicated CDS services to technical clien Like with xflights, clone [`xtravels-java`](https://github.com/capire/xtravels-java/tree/main) or, if already cloned and modified locally, reset to remote branch. The remote service can be configured in a very similar way as with [co-located services](#co-located-consumer). -You only need to add the information about the IAS dependency to be called (`ias-dependency-name`). +You only need to add the information about the IAS dependency to be called. +In Java, this is configured via `ias-dependency-name`. In Node.js, the IAS dependency is resolved through a BTP destination configured with IAS authentication, where the SAP Cloud SDK handles the token exchange. + The name for the IAS dependency is flexible but **needs to match the chosen name in the next step** when [connecting consumer and provider in IAS](#connect). ::: code-group -```yaml [/srv/srv/main/resources/application.yaml] +```yaml [Java: application.yaml] spring: config.activate.on-profile: cloud cds: @@ -333,15 +377,56 @@ cds: ias-dependency-name: data-consumer ``` +```json [Node.js: package.json] +{ + "cds": { + "requires": { + "xflights": { + "kind": "hcql", + "model": "sap.capire.flights.data", + "[production]": { + "credentials": { + "path": "/hcql", + "destination": "xflights-api" + } + } + } + } + } +} +``` + ::: +In Node.js, the `destination` property refers to a BTP destination that must be configured with IAS authentication. +The SAP Cloud SDK automatically handles the IAS App-2-App token exchange when the destination is configured appropriately. + +::: tip Node.js: BTP Destination for IAS App-2-App +Create a BTP destination `xflights-api` with: +- **URL**: `https://` +- **Authentication**: `OAuth2UserTokenExchange` or `OAuth2JWTBearer` +- **Token Service URL**: Your IAS tenant token endpoint +- Configure the IAS dependency name in the destination's additional properties + +The SAP Cloud SDK resolves the IAS dependency and performs the token exchange transparently. +::: + +[Learn more about SAP Cloud SDK IAS authentication](https://sap.github.io/cloud-sdk/docs/js/features/connectivity/identity-authentication-service){.learn-more} + Finally, deploy and start the application with -```sh +::: code-group +```sh [Java] cd ./xtravels_java cds up ``` +```sh [Node.js] +cd ./xtravels +cds up +``` +::: + `xtravels-srv` is not expected to start successfully; instead, you should see error log messages like this: ```yaml Remote HCQL service responded with HTTP status code '401', ... @@ -361,7 +446,7 @@ Open the Administrative Console for the IAS tenant (see prerequisites [here](./a 1. Select **Applications & Resources** > **Applications**. Choose the IAS application of the `xtravels` consumer from the list. 2. In **Application APIs** select **Dependencies** and click on **Add**. -3. Type `data-consumer` as dependency name (needs to match property value `ias-dependency-name`) and pick provided API `data-consumer` from the provider IAS application `xflights`. +3. Type `data-consumer` as dependency name (needs to match property value `ias-dependency-name` in Java, or the IAS dependency configured in the BTP destination for Node.js) and pick provided API `data-consumer` from the provider IAS application `xflights`. 4. Confirm with **Save** ::: details Create IAS dependency in Administrative Console @@ -390,6 +475,28 @@ To do so, assign a proper AMS policy (e.g., `admin`) to the test user as describ
+## Node.js: SAP Cloud SDK Requirement { #nodejs-cloud-sdk } + +For IAS-based authentication scenarios (App-2-App, BTP Reuse Services), CAP Node.js relies on the [SAP Cloud SDK](https://sap.github.io/cloud-sdk/) to handle token exchange and destination resolution. + +::: tip Install SAP Cloud SDK +Add the SAP Cloud SDK packages to your project: +```sh +npm add @sap-cloud-sdk/http-client @sap-cloud-sdk/connectivity @sap-cloud-sdk/resilience +``` +::: + +The Cloud SDK provides: +- **IAS token exchange** for App-2-App flows +- **BTP Destination resolution** with various authentication types +- **Resilience features** like timeout, retry, and circuit breaker + +For simple scenarios (local development, basic authentication, direct token forwarding), CAP Node.js can use native `fetch` as a fallback when Cloud SDK is not installed. +However, for production deployments with IAS authentication, the Cloud SDK is required. + +[Learn more about SAP Cloud SDK connectivity features](https://sap.github.io/cloud-sdk/docs/js/features/connectivity/destinations){.learn-more} + + ## Pitfalls - **Don't write custom integration logic** for consumed services. From 3696aa2cd1f3249de6f5dbd0f9230498a18c0df2 Mon Sep 17 00:00:00 2001 From: D051920 Date: Thu, 28 May 2026 18:09:54 +0200 Subject: [PATCH 2/4] changes in ias --- guides/security/remote-authentication.md | 58 ++++++++++++++---------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/guides/security/remote-authentication.md b/guides/security/remote-authentication.md index bbe3e5a8b..846d0cca8 100644 --- a/guides/security/remote-authentication.md +++ b/guides/security/remote-authentication.md @@ -61,9 +61,12 @@ Technically, **they share the same identity instance, which allows direct token [Learn more about how to configure co-located services in CAP Java](/java/cqn-services/remote-services#binding-to-a-service-with-shared-identity) {.learn-more} [Learn more about how to configure remote services in CAP Node.js](/node.js/remote-services) {.learn-more} -You can test CAP's built-in support for co-located services in practice by modifying the [`xflights-java`](https://github.com/capire/xflights-java/tree/main) and [`xtravels-java`](https://github.com/capire/xtravels-java/tree/main) sample applications. -`xflights-java` acts as a master data provider exposing basic flight data in service [`sap.capire.flights.data`](https://github.com/capire/xflights-java/blob/6fc7c665c63bb6d73e28c11b391b1ba965b8772c/srv/data-service.cds#L24) via different protocols. -On the client side, `xtravels-java` imports this service as a CAP remote service and fetches data in a [custom handler for data federation](https://github.com/capire/xtravels-java/blob/53a5fa33caf4c9068f2e66fab25bda26f3f450ca/srv/src/main/java/sap/capire/xtravels/handler/FederationHandler.java#L63). +You can test CAP's built-in support for co-located services in practice by modifying the sample applications: +- **Java**: [`xflights-java`](https://github.com/capire/xflights-java/tree/main) and [`xtravels-java`](https://github.com/capire/xtravels-java/tree/main) +- **Node.js**: [`xflights`](https://github.com/capire/xflights/tree/main) and [`xtravels`](https://github.com/capire/xtravels/tree/main) + +`xflights` acts as a master data provider exposing basic flight data in service `sap.capire.flights.data` via different protocols. +On the client side, `xtravels` imports this service as a CAP remote service and fetches data for federation. ::: tip CAP offers a simplified co-located service setup by leveraging remote services that require: @@ -185,11 +188,12 @@ For different [user propagation](./cap-users#remote-services) modes the remote s The provider service authorization needs to align with the configured user propagation. ::: -Additionally, to establish the co-located setup, the microservice needs to share the same identity instance: +Additionally, to establish the co-located setup, the microservice needs to share the same identity instance. +This is configured in the MTA deployment descriptor and applies to both Java and Node.js: ::: code-group -```yaml [/srv/srv/main/resources/application.yaml] +```yaml [mta.yaml] resources: - name: xflights-ias type: org.cloudfoundry.managed-service # [!code --] @@ -290,7 +294,7 @@ CAP offers a simplified App-2-App setup by leveraging remote services that requi #### 1. Prepare and deploy the provider application -Assuming the same local CF environment setup as [here](#prepare), clone [`xflights-java`](https://github.com/capire/xflights-java/tree/main) or, if already cloned and modified locally, reset to the remote branch. +Assuming the same local CF environment setup as [here](#prepare), clone the sample application ([`xflights-java`](https://github.com/capire/xflights-java/tree/main) or [`xflights`](https://github.com/capire/xflights/tree/main) for Node.js), or if already cloned and modified locally, reset to the remote branch. Similar to the [co-located](#co-located-provider) variant, `xflights` needs to expose service `sap.capire.flights.data` to technical clients. The difference is that the consumers are not known a priori and are not part of the same application deployment. @@ -331,11 +335,18 @@ annotate data with @(requires: 'data-consumer'); Finally, deploy and start the application with -```sh +::: code-group +```sh [Java] cd ./xflights_java cds up ``` +```sh [Node.js] +cd ./xflights +cds up +``` +::: + ::: tip API as CAP role The API identifiers exposed by the IAS instance in list `provided-apis` are granted as CAP roles after successful authentication and can be used in @requires annotations. @@ -349,11 +360,16 @@ Instead of using the same role, expose dedicated CDS services to technical clien #### 2. Prepare and deploy the consumer application { #consumer } -Like with xflights, clone [`xtravels-java`](https://github.com/capire/xtravels-java/tree/main) or, if already cloned and modified locally, reset to remote branch. +Like with xflights, clone the sample application ([`xtravels-java`](https://github.com/capire/xtravels-java/tree/main) or [`xtravels`](https://github.com/capire/xtravels/tree/main) for Node.js), or if already cloned and modified locally, reset to remote branch. The remote service can be configured in a very similar way as with [co-located services](#co-located-consumer). You only need to add the information about the IAS dependency to be called. -In Java, this is configured via `ias-dependency-name`. In Node.js, the IAS dependency is resolved through a BTP destination configured with IAS authentication, where the SAP Cloud SDK handles the token exchange. + +::: tip Java vs Node.js configuration +**Java** provides a convenient shortcut via `ias-dependency-name` that configures the IAS App-2-App flow directly in `application.yaml`. + +**Node.js** uses the standard BTP destination approach for all outbound authentication. Configure a BTP destination with IAS authentication in BTP Cockpit, then reference it by name. +::: The name for the IAS dependency is flexible but **needs to match the chosen name in the next step** when [connecting consumer and provider in IAS](#connect). @@ -398,17 +414,12 @@ cds: ::: -In Node.js, the `destination` property refers to a BTP destination that must be configured with IAS authentication. -The SAP Cloud SDK automatically handles the IAS App-2-App token exchange when the destination is configured appropriately. - -::: tip Node.js: BTP Destination for IAS App-2-App -Create a BTP destination `xflights-api` with: +::: tip Node.js: BTP Destination configuration +Create a BTP destination `xflights-api` in BTP Cockpit with: - **URL**: `https://` -- **Authentication**: `OAuth2UserTokenExchange` or `OAuth2JWTBearer` +- **Authentication**: `OAuth2JWTBearer` - **Token Service URL**: Your IAS tenant token endpoint -- Configure the IAS dependency name in the destination's additional properties - -The SAP Cloud SDK resolves the IAS dependency and performs the token exchange transparently. +- **Additional Properties**: Configure the IAS dependency name ::: [Learn more about SAP Cloud SDK IAS authentication](https://sap.github.io/cloud-sdk/docs/js/features/connectivity/identity-authentication-service){.learn-more} @@ -432,8 +443,7 @@ cds up Remote HCQL service responded with HTTP status code '401', ... ``` -Technically, the remote service implementation initiates an App-2-App flow. -It takes the token from the request and triggers an IAS token exchange for the target [IAS dependency](#connect) according to the user propagation strategy (technical communication here). +Technically, the remote service implementation initiates an App-2-App flow, taking the token from the request and triggering an IAS token exchange for the target [IAS dependency](#connect). As the IAS dependency is not created yet, IAS rejects the token exchange request and the call to the provider fails with `401` (not authenticated). Note that property `oauth2-configuration.token-policy.access-token-format: jwt` is set in the identity instance to ensure the exchanged token has JWT format. @@ -477,7 +487,7 @@ To do so, assign a proper AMS policy (e.g., `admin`) to the test user as describ ## Node.js: SAP Cloud SDK Requirement { #nodejs-cloud-sdk } -For IAS-based authentication scenarios (App-2-App, BTP Reuse Services), CAP Node.js relies on the [SAP Cloud SDK](https://sap.github.io/cloud-sdk/) to handle token exchange and destination resolution. +For BTP destination-based authentication scenarios, CAP Node.js relies on the [SAP Cloud SDK](https://sap.github.io/cloud-sdk/) to handle destination resolution and token exchange. ::: tip Install SAP Cloud SDK Add the SAP Cloud SDK packages to your project: @@ -487,12 +497,12 @@ npm add @sap-cloud-sdk/http-client @sap-cloud-sdk/connectivity @sap-cloud-sdk/re ::: The Cloud SDK provides: -- **IAS token exchange** for App-2-App flows -- **BTP Destination resolution** with various authentication types +- **BTP Destination resolution** with various authentication types, including IAS +- **Token exchange** when configured via BTP destinations - **Resilience features** like timeout, retry, and circuit breaker For simple scenarios (local development, basic authentication, direct token forwarding), CAP Node.js can use native `fetch` as a fallback when Cloud SDK is not installed. -However, for production deployments with IAS authentication, the Cloud SDK is required. +However, for production deployments with BTP destinations, the Cloud SDK is required. [Learn more about SAP Cloud SDK connectivity features](https://sap.github.io/cloud-sdk/docs/js/features/connectivity/destinations){.learn-more} From 1223b4d77e0c66758d26bf35ab1ae2dd00839694 Mon Sep 17 00:00:00 2001 From: D051920 Date: Fri, 29 May 2026 17:00:39 +0200 Subject: [PATCH 3/4] test and rewrite co-located services --- guides/security/remote-authentication.md | 56 ++++++++++++++---------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/guides/security/remote-authentication.md b/guides/security/remote-authentication.md index 846d0cca8..617227f5b 100644 --- a/guides/security/remote-authentication.md +++ b/guides/security/remote-authentication.md @@ -39,7 +39,7 @@ At the connectivity layer, the following basic tasks can be addressed genericall - Destination (_how to find the target service_) - User propagation (_how to transport user information_) -CAP's connectivity component handles authentication (IAS, XSUAA, X.509, ZTID, ...), destination (local destination, BTP Destination, BTP Service Binding), and user propagation (technical provider, technical subscriber, named user) transparently through configuration. +CAP's connectivity component handles authentication (IAS, XSUAA, X.509, ZTID, ...), destination (local destination, BTP Destination, BTP Service Binding), and user propagation (technical provider, technical subscriber, named user) transparently through configuration (although the configuration approach may differ between Java and Node.js). All three service scenarios can be addressed through configuration variants of the same remote service concept, as shown in the following sections. CAP supports out-of-the-box consumption of various types of [remote services]( #remote-services): @@ -114,12 +114,11 @@ cds: { "cds": { "requires": { - "xflights": { + "sap.capire.flights.data": { "kind": "hcql", - "model": "sap.capire.flights.data", "[production]": { "credentials": { - "url": "https:///hcql", + "url": "https:///hcql/data", "forwardAuthToken": true } } @@ -130,23 +129,28 @@ cds: ``` ::: -The `type` (Java) or `kind` (Node.js) property activates the protocol for exchanging business data and must be offered by the provider [CDS service](https://github.com/capire/xflights-java/blob/6fc7c665c63bb6d73e28c11b391b1ba965b8772c/srv/data-service.cds#L24). +::: details Java configuration explained + +The `type` property activates the protocol for exchanging business data and must be offered by the provider [CDS service](https://github.com/capire/xflights-java/blob/6fc7c665c63bb6d73e28c11b391b1ba965b8772c/srv/data-service.cds#L24). The `model` property needs to match the fully qualified name of the CDS service from the imported model. You can find CDS service definition of `sap.capire.flights.data` in file `target/cds/capire/xflight-data/service.cds` resolved during CDS build step. +The `binding.name` needs to point to the shared identity instance and `options.url` together with `http.suffix` provides the required location of the remote service endpoint. +Finally, `onBehalfOf: systemUser` specifies that the remote call is invoked on behalf of a technical user in context of the tenant. -In Java, the `binding.name` needs to point to the shared identity instance and `options.url` together with `http.suffix` provides the required location of the remote service endpoint. -In Node.js, `credentials.url` provides the full endpoint URL, and `forwardAuthToken: true` enables direct forwarding of the incoming JWT token to the provider service. +::: -Finally, `onBehalfOf: systemUser` (Java) specifies that the remote call is invoked on behalf of a technical user in context of the tenant. +::: details Node.js configuration explained + +The `kind` property activates the protocol for exchanging business data (same as `type` in Java). +The key in `cds.requires` must match the fully qualified CDS service name (e.g., `sap.capire.flights.data`), which is the same name used in `cds.connect.to()`. +The `credentials.url` provides the full endpoint URL including the service path `/hcql/data`. +The `forwardAuthToken: true` enables direct forwarding of the incoming JWT token to the provider service - this is suitable for co-located services that share the same identity instance, as the token is already valid for the provider. -::: tip -On behalf of `systemUser` works both in pure single tenant and in pure multitenant scenarios. -If you are consuming a single tenant service from within a multitenant application choose on behalf of `systemUserProvider`. ::: -::: tip Node.js token forwarding -In Node.js, `forwardAuthToken: true` forwards the incoming request's JWT token directly to the provider. -This is suitable for co-located services that share the same identity instance, as the token is already valid for the provider. +::: tip +On behalf of `systemUser` (Java) works both in pure single tenant and in pure multitenant scenarios. +If you are consuming a single tenant service from within a multitenant application choose on behalf of `systemUserProvider`. ::: Now you are ready to deploy the application with @@ -189,7 +193,7 @@ The provider service authorization needs to align with the configured user propa ::: Additionally, to establish the co-located setup, the microservice needs to share the same identity instance. -This is configured in the MTA deployment descriptor and applies to both Java and Node.js: +This is configured in the MTA deployment descriptor (applies to both Java and Node.js): ::: code-group @@ -397,12 +401,11 @@ cds: { "cds": { "requires": { - "xflights": { + "sap.capire.flights.data": { "kind": "hcql", - "model": "sap.capire.flights.data", "[production]": { "credentials": { - "path": "/hcql", + "path": "/hcql/data", "destination": "xflights-api" } } @@ -487,10 +490,20 @@ To do so, assign a proper AMS policy (e.g., `admin`) to the test user as describ ## Node.js: SAP Cloud SDK Requirement { #nodejs-cloud-sdk } -For BTP destination-based authentication scenarios, CAP Node.js relies on the [SAP Cloud SDK](https://sap.github.io/cloud-sdk/) to handle destination resolution and token exchange. +CAP Node.js can handle remote service calls in two ways: + +**Without Cloud SDK** (native fetch): +- Direct URL with `forwardAuthToken: true` (co-located services) +- Direct URL with `BasicAuthentication` +- Local development scenarios + +**With Cloud SDK** (required): +- BTP destination-based authentication (including IAS App-2-App) +- OAuth2 token exchange scenarios +- On-premise connectivity via Cloud Connector ::: tip Install SAP Cloud SDK -Add the SAP Cloud SDK packages to your project: +When using BTP destinations, add the SAP Cloud SDK packages to your project: ```sh npm add @sap-cloud-sdk/http-client @sap-cloud-sdk/connectivity @sap-cloud-sdk/resilience ``` @@ -501,9 +514,6 @@ The Cloud SDK provides: - **Token exchange** when configured via BTP destinations - **Resilience features** like timeout, retry, and circuit breaker -For simple scenarios (local development, basic authentication, direct token forwarding), CAP Node.js can use native `fetch` as a fallback when Cloud SDK is not installed. -However, for production deployments with BTP destinations, the Cloud SDK is required. - [Learn more about SAP Cloud SDK connectivity features](https://sap.github.io/cloud-sdk/docs/js/features/connectivity/destinations){.learn-more} From 1989b74761ee752d3d097d3659d0f1ef923389f9 Mon Sep 17 00:00:00 2001 From: D051920 Date: Fri, 29 May 2026 18:21:11 +0200 Subject: [PATCH 4/4] continued --- guides/security/remote-authentication.md | 110 +++++++++++++++++++---- 1 file changed, 93 insertions(+), 17 deletions(-) diff --git a/guides/security/remote-authentication.md b/guides/security/remote-authentication.md index 617227f5b..52a05d7b4 100644 --- a/guides/security/remote-authentication.md +++ b/guides/security/remote-authentication.md @@ -270,7 +270,7 @@ As a consequence, external services can run cross-regionally; even non-BTP syste A prerequisite for external service calls is a trust federation between the consumer and the provider system. A seamless integration experience for external service communication is provided by [IAS App-2-App](#app-to-app) flows, which are offered by CAP via remote services. -Alternatively, remote services can be configured on top of [BTP HTTP Destinations](../services/consuming-services#using-destinations) that offer [various authentication strategies](https://help.sap.com/docs/connectivity/sap-btp-connectivity-cf/http-destinations) such as SAML 2.0 as required by many S/4 system endpoints. +[BTP HTTP Destinations](../services/consuming-services#using-destinations) offer [various authentication strategies](https://help.sap.com/docs/connectivity/sap-btp-connectivity-cf/http-destinations) such as SAML 2.0 as required by many S/4 system endpoints. Note that CAP Node.js uses BTP Destinations also for IAS App-2-App flows, while CAP Java handles IAS token exchange natively. ### IAS App-2-App { #app-to-app } @@ -311,15 +311,37 @@ resources: - name: xflights-ias type: org.cloudfoundry.managed-service parameters: - [...] + service: identity + service-plan: application config: display-name: xflights - provided-apis: # [!code ++:5] + oauth2-configuration: + token-policy: + access-token-format: jwt + provided-apis: - name: data-consumer description: Grants technical access to data service API ``` ::: +For Node.js, additionally configure the authentication strategy in `package.json`: + +::: code-group +```json [Node.js: package.json] +{ + "cds": { + "requires": { + "auth": { + "[production]": { + "kind": "ias" + } + } + } + } +} +``` +::: + The entry with name `data-consumer` represents the consumption of service `sap.capire.flights.data` and is exposed as IAS API. The description helps administrators to configure the consumer application with the proper provider API if done on UI level. @@ -368,13 +390,6 @@ Like with xflights, clone the sample application ([`xtravels-java`](https://gith The remote service can be configured in a very similar way as with [co-located services](#co-located-consumer). You only need to add the information about the IAS dependency to be called. - -::: tip Java vs Node.js configuration -**Java** provides a convenient shortcut via `ias-dependency-name` that configures the IAS App-2-App flow directly in `application.yaml`. - -**Node.js** uses the standard BTP destination approach for all outbound authentication. Configure a BTP destination with IAS authentication in BTP Cockpit, then reference it by name. -::: - The name for the IAS dependency is flexible but **needs to match the chosen name in the next step** when [connecting consumer and provider in IAS](#connect). ::: code-group @@ -401,6 +416,11 @@ cds: { "cds": { "requires": { + "auth": { + "[production]": { + "kind": "ias" + } + }, "sap.capire.flights.data": { "kind": "hcql", "[production]": { @@ -417,15 +437,71 @@ cds: ::: -::: tip Node.js: BTP Destination configuration -Create a BTP destination `xflights-api` in BTP Cockpit with: -- **URL**: `https://` -- **Authentication**: `OAuth2JWTBearer` -- **Token Service URL**: Your IAS tenant token endpoint -- **Additional Properties**: Configure the IAS dependency name +::: details Java configuration explained + +The `ias-dependency-name` property configures the IAS App-2-App flow directly in `application.yaml`. This is all that's needed for Java - the CAP Java runtime handles the token exchange automatically. + ::: -[Learn more about SAP Cloud SDK IAS authentication](https://sap.github.io/cloud-sdk/docs/js/features/connectivity/identity-authentication-service){.learn-more} +::: details Node.js configuration explained + +Node.js uses BTP destinations for outbound authentication, which requires additional setup: + +**1. MTA descriptor** - bind both IAS and destination services: + +```yaml +modules: + - name: xtravels-srv + [...] + requires: + - name: xtravels-ias + - name: xtravels-destination + +resources: + - name: xtravels-ias + type: org.cloudfoundry.managed-service + parameters: + service: identity + service-plan: application + config: + display-name: xtravels + oauth2-configuration: + token-policy: + access-token-format: jwt + + - name: xtravels-destination + type: org.cloudfoundry.managed-service + parameters: + service: destination + service-plan: lite +``` + +**2. SAP Cloud SDK dependencies** - required for destination-based authentication: + +```sh +npm add @sap-cloud-sdk/http-client @sap-cloud-sdk/connectivity @sap-cloud-sdk/resilience +``` + +See [Node.js: SAP Cloud SDK Requirement](#nodejs-cloud-sdk) for more details. + +**3. BTP Destination** - create `xflights-api` in BTP Cockpit (Connectivity → Destinations): + +- **Name**: `xflights-api` +- **Type**: HTTP +- **URL**: `https://` +- **ProxyType**: Internet +- **Authentication**: `OAuth2JWTBearer` +- **Client ID**: from `xtravels-ias` service key +- **Client Secret**: from `xtravels-ias` service key +- **Token Service URL**: `https://.accounts.ondemand.com/oauth2/token` + +To get the Client ID and Secret, create a service key: +```sh +cf create-service-key xtravels-ias xtravels-ias-key +cf service-key xtravels-ias xtravels-ias-key +``` + +::: Finally, deploy and start the application with