Homelab, Linux, JS & ABAP (~˘▾˘)~
 

[CAP] Multitenant Job Scheduler – Fixing Scope issue

When I was integrating the Job Scheduler service into my Multitenant Application, I ran into the following JWT Token issue, when the Job Scheduler was calling my CAP action. Means the job creation was already working fine and was also displaying the right tenant for my job, but the Job Scheduler was not able to successfully call the given endpoint. This is the error I got in the logs:

Error: Jwt token with audience: [
'sb-a1e9d3b8-2bee-47db-xxxx-07e5a54aec1e!b180208|sap-jobscheduler!b3',
'uaa'
] is not issued for these clientIds: [
'sb-MyApp-mtdev-App!t180208',
'MyAp-mtdev-App!t180208'
].

After reading some of the great blogs from Carlos Roggan, I noticed that I forgot to grant the Job Scheduler the necessary authority to actual call my CAP action. So I added the following lines to the xs-security.json file

    {
      "name": "$XSAPPNAME.jobscheduler",
      "description": "Scope for Job Scheduler",
      "grant-as-authority-to-apps": [
        "$XSSERVICENAME(job-scheduler)"
      ]
    }

and also annotated my CAP action using the new scope @(requires: ['jobscheduler']).

I redeployed everything, but the issue still persists. 🙁

Turned out, for the standard plan, tokens are cached in Job Scheduler up to 12 hours.

https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/secure-access?locale=en-US

After waiting 12 hours, the endpoint was successfully called by the Job Scheduler. 🙂

[CAP] Get subdomain in a multitenant scenario

Until recently, I was always decoded the JWT to get the subdomain of a subscribed tenant like this:

const jwt = retrieveJwt(req)
const subdomain = decodeJwt(jwt).ext_attr.zdn

I now noticed that you can also use the original request object and the getSubdomain function of the authInfo object. It’s provided by @sap/xssec and is only available when using XSUAA, means not with mocked authentication. This way you can get the subdomain in a single line:

const subdomain = req.http.req.authInfo.getSubdomain()

And there are some more helpful functions, that are documented here: