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 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:
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 => {
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="https://blogs.sap.com/user-info/userInfoUAA()">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 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:
Figure 2 - Terminal menu
Now, your
Terminal window, should have been
split into two like demonstrated below:
Figure 3 - Split Terminal
Let's f
irst start the backend 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 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 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