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 of 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:
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 => {
const user = {
id : req.user.id,
tenant : req.user.tenant,
_roles: req.user._roles,
attr : req.user.attr
}
return 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:
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 to 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:
Now, your Terminal window, should have been split into two like demonstrated below:
Let’s first start the backend service. In the first Terminal run the command:
cds watch --profile hybrid
This should be the expected outcome:
In the second Terminal move to the app directory (cd app) and run the command:
npm run start
This should be the expected outcome:
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:
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:
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:
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