3 weeks ago
On the BTP (CF Runtime) I have two servers (CAP NodeJs apps) that are bound to the same XSUAA instance. I would like them to communicate in background jobs (server-to-server). This currently fails on the BTP (403) as the endpoints require app-specific roles which are not included in the token obtained by the OAuth2 ClientCredentials grant flow. According to the xs-security.json documentation scopes may be granted to "authorities" when using the ClientCredentials grant flow. How do I modify the single xs-security.json (see below) used by the XSUAA to make it work?
An example repo can be found here . The explanation is as follows.
The scenario contains two servers: producer and consumer. Once the producer server is served, a background job is started which periodically POSTs the `consume` endpoint of consumer that requires the role "Admin".
// simplified producer init()
cds.once("served", () => {
cds.spawn({ every: INTERVAL }, async () => {
const msg = `Message #${++msgCount}`;
cds.log("Producer").log("Producing: ", msg);
const consumerSrv = await cds.connect.to("ConsumerService");
await consumerSrv.send("consume", {
msg: msg,
});
});
});
service ConsumerService @(path: '/api/consumer/') {
@(requires: ['Admin'])
action consume(msg : String);
}
// consumer init()
public async init(): Promise<void> {
await super.init();
const ConsumerService = await import("../@cds-models/ConsumerService");
this.on(ConsumerService.consume, (req) => {
cds.log("Consumer").log("Consuming message of user ", req.user?.id, " : ", req.data.msg);
});
}
The cds.requires section of producer looks like this:
"requires": {
"ConsumerService": {
"kind": "odata",
"model": "example.consumer",
"credentials": {
"path": "/api/consumer/",
"[production]": { "destination": "consumer-api" },
"[development]": {
"destination": {
"name": "consumer-api",
"url": "http://localhost:4005",
"username": "admin",
"password": "admin"
}
}
}
},
"auth": {
"[production]": { "kind": "xsuaa" },
"[development]": {
"kind": "basic",
"users": {
"admin": {
"password": "admin",
"roles": ["Admin"]
}
}
}
}
},
During deployment the destination "consumer-api" is created. The manifest.yaml looks like this:
_schema-version: "3.1"
ID: backgroundjobs
version: 1.0.0
description: "Example project for server-to-server communication in background jobs"
parameters:
enable-parallel-deployments: true
modules:
# --------------------- PRODUCER MODULE ------------------------
- name: backgroundjobs-producer
# ------------------------------------------------------------
type: nodejs
path: ../dist/srv/producer
parameters:
buildpack: nodejs_buildpack
memory: 128MB
disk-quota: 128MB
command: node ./node_modules/@sap/cds/bin/cds-serve --profile production
properties:
OPTIMIZE_MEMORY: true
build-parameters:
builder: custom
commands: []
requires:
- name: backgroundjobs-uaa
- name: backgroundjobs-destination
- name: backgroundjobs-consumer
provides:
- name: producer-api
properties:
srv-url: ${default-url}
# --------------------- CONSUMER MODULE ------------------------
- name: backgroundjobs-consumer
# ------------------------------------------------------------
type: nodejs
path: ../dist/srv/consumer
parameters:
buildpack: nodejs_buildpack
memory: 128MB
disk-quota: 128MB
command: node ./node_modules/@sap/cds/bin/cds-serve --profile production
properties:
OPTIMIZE_MEMORY: true
build-parameters:
builder: custom
commands: []
requires:
- name: backgroundjobs-uaa
- name: backgroundjobs-destination
provides:
- name: consumer-api
properties:
srv-url: ${default-url}
# ---------------------- DESTINATIONS --------------------------
- name: backgroundjobs-destination-content
# ------------------------------------------------------------
type: com.sap.application.content
build-parameters:
no-source: true
requires:
- name: backgroundjobs-destination
parameters:
content-target: true
- name: consumer-api
- name: backgroundjobs-uaa
parameters:
service-key:
name: ${org}-${space}-backgroundjobs-uaa-key
parameters:
content:
instance:
existing_destinations_policy: update
destinations:
- Name: consumer-api
URL: ~{consumer-api/srv-url}
WebIDEEnabled: true
Authentication: OAuth2ClientCredentials
HTML5.ForwardAuthToken: false # when enabled, the ClientCredentials flow is not triggered and we need that in background jobs
TokenServiceURLType: Dedicated
TokenServiceInstanceName: ${org}-${space}-backgroundjobs-uaa
TokenServiceKeyName: ${org}-${space}-backgroundjobs-uaa-key
resources:
- name: backgroundjobs-uaa
type: org.cloudfoundry.managed-service
parameters:
service-name: ${org}-${space}-backgroundjobs-uaa
service: xsuaa
service-plan: application
path: ./xs-security.json
config:
xsappname: ${org}-${space}-backgroundjobs
service-keys:
- name: ${org}-${space}-backgroundjobs-uaa-key
- name: backgroundjobs-destination
type: org.cloudfoundry.managed-service
parameters:
service-name: ${org}-${space}-backgroundjobs-destination
service: destination
service-plan: lite
And the xs-security.json:
{
"xsappname": "${default-xsappname}",
"tenant-mode": "dedicated",
"scopes": [
{
"name": "$XSAPPNAME.Admin"
}
],
"attributes": [],
"role-templates": [
{
"name": "Admin",
"description": "",
"scope-references": ["$XSAPPNAME.Admin"],
"attribute-references": []
}
],
"oauth2-configuration": {
"redirect-uris": ["https://*.hana.ondemand.com/**"]
}
}
Request clarification before answering.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
84 | |
29 | |
9 | |
9 | |
8 | |
8 | |
7 | |
6 | |
6 | |
6 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.