How to get authenticated user information with CAP in three different ways – Using the XSUAA API


Prerequisite

To follow-up with this blog post you must have read and completed the post: Setup project for development.

Reference the XSUAA Service

The third approach to get the authenticated user information is the most enhanced and complete one as it gets many available user data, such as ID in the source IdP, internal BTP ID and previous logon time.

It relies on the features of the Authentication and Trust Management service (namely XSUAA) accessible via REST API (/userinfo endpoint).

The good news is that the XSUAA service instance is already bound to the CAP servie, so we just need to reference it in the CAP service as the credentials of an external service. We do it by adding a “cds.requires” section to the package.json file of the CAP service.

Open-up the package.json of the CAP service (the one in the root folder or your project) and copy and paste the following code snippet right before the last curly bracket of the file:

 , "cds": { "requires": { "xsuaa_api": { "kind": "rest", "credentials": { "url": "<from XSUAA service binding>", "forwardAuthToken" : true } } } }

After the modification your package.json file should look like this:

Figure 8 – cds.requires added to package.json

Notice that the URL to the service host will be fetched on the fly from the XSUAA service binding, so we just leave it there as a placeholder.

Modify the “userInfoUAA” Function Handler

Now it’s time to update the code of the function handler (userInfoUAA) which will call the XSUAA API to get the authenticated user information.

As we have previously prepared a “skeleton” to implement the code for this approach (via the userInfoUAA function), now we just need to connect to the external service and replace the ‘return “”;‘ with the appropriate code to call it.

In this approach we will just return the information fetched by the “/userinfo” endpoint of the XSUAA service host.

Now, open-up the user-info-service.js file, and modify the code like demonstrated below:

NOTE:  we also modified the userInfo function to preserve the code in case you’ve already completed the second approach (using the CAP request object).

module.exports = cds.service.impl(async function () { // API reference const api = 'xsuaa_api'; // Get the XSUAA host URL from service binding const xsuaa_bind = JSON.parse(process.env.VCAP_SERVICES).xsuaa[0]; const api_def = cds.env.requires[api]; api_def.credentials.url = xsuaa_bind.credentials.url; // connect to the XSUAA host const xsuaa = await cds.connect.to(api_def); // using req.user approach (user attribute - of class cds.User - from the request object) this.on('userInfo', req => { return req.user; }); // using the XSUAA API this.on('userInfoUAA', async () => { return await xsuaa.get("/userinfo"); });
});

Adjust the Index Page

The code is executed by accessing the “/user-info/userInfoUAA()” endpoint. So, let’s just set it as a link in the index.html page by modifying this line:

 <li><a href="/user-info/userInfoUAA()"></a>3. Using the XSUAA API</a></li>

By doing so, your index.html file should now look like this:

Figure 1 – New link in index.html

NOTE: if you haven’t completed the post for the first and/or second approaches (directly from the HTML5 app and/or using the CAP request object) your index.html file might look slightly different (no links for the first and/or second approaches).

Test the Approach

As previously mentioned this approach relies on the backend service. Therefore, the service must be running for it work properly.

NOTE: you might have already executed the steps to split the Terminal if you completed the post for the second approach (using the CAP request object), so you may skip them.

In the Terminal, let’s make sure to be positioned in the project root folder (“user-info“) – if not already there. If you where running the first approach you might have ended up in the “app” folder after pressing CTRL-C, so just go back with: cd ..

Click on the prompt in the current opened Terminal, then in the top menu of Business Application Studio click on Terminal and select Split Terminal:

Figure%202%20-%20Terminal%20menu

Figure 2 – Terminal menu

Now, your Terminal window, should have been split into two like demonstrated below:

Figure%203%20-%20Split%20Terminal

Figure 3 – Split Terminal

Let’s first start the back end service. In the first Terminal run the command:

cds watch --profile hybrid

This should be the expected outcome:

Figure 4 – Backend service started

In the second Terminal move to the app directory (cd app) and run the command:

npm run start

This should be the expected outcome:

Figure%205%20-%20AppRouter%20started

Figure 5 – AppRouter started

And, after a few seconds, you should see a pop-up in the bottom-right corner of Business Application Studio with a button to open the application in a new tab:

Figure%203%20-%20Pop-up%20to%20open%20app%20in%20new%20tab

Figure 6 – Pop-up to open app in new tab

Click on that button to access the application’s index page: at this point the AppRouter will execute the OAuth 2.0 authentication flow (login) and display the index.html page:

Figure 7 – Application index page

NOTE: If you haven’t completed the post for the first and/or second approaches (directly from the HTML5 app and/or using the CAP request object) that page might look slightly different (no links for the first and/or second approaches).

Click on the “3. Using the XSUAA API” link (the /user-info/userInfoUAA() endpoint) and the user information should be displayed in JSON format like demonstrated below:

Figure 8 – Information fetched from /userinfo

As you can see, additionally to the information retrieved in the first approach, you get the BTP internal user ID, the check for e-mail verification, the user ID in the source IdP and the previous logon time. This is indeed a much richer set of information.

Using the internal BTP user ID you can get even more (such as the role collections assigned to the user on BTP) by creating an XSUAA service instance of plan apiaccess and call the /Users/{user ID} endpoint to fetch everything associated to the user in the platform – you can deep dive into this topic of Using APIs of the SAP Authorization and Trust Management Service by reading this page from the SAP Help Portal.

Conclusion

After having gone through the steps of this blog post you should have successfully fetched authenticated user information in the backend service leveraging the XSUAA API from the Authentication and Trust Management BTP service. The next step would be to try one of the other different approaches proposed in this blog posts series (if not yet done).

Please, do not hesitate to submit your questions in SAP Community through the Q&A tag link: https://answers.sap.com/index.html

Other blog posts in this series

  • Directly from the UI (HTML5 app)
  • Using the CAP request object