Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
lalitmohan
Product and Topic Expert
Product and Topic Expert
The availability of different environments on SCP gives us the choices for technologies, runtime, and services which allows us a lot of flexibility in our development process.

We have a service in SCP(NEO Environment) to get information about the currently logged-in user. It's known as the UserInfo service. For more details, see How to get UserName and other login info in SAP UI5 application | SAP Blogs. This was well-documented and worked well on the NEO platform.

The simplest approach is to include UserInfo service details in the neo-app.js file, which will allow you to access user data through the application URL.



This service is no longer functional as we move towards Cloud foundry but the User Authorization and Access (UAA) or XSUAA service manages user identity while operating in a cloud foundry space. To obtain an OAuth token, the service will use the required OAuth2 flows. SAP has created a separate project to incorporate these flows due to the complexity of doing so. The App-Router checks to see if the incoming request is authenticated, and if it isn't, it manages the exchange between the browser and the XSUAA service to log you into the application.

When a request is sent, the user information (which should always be present since all routes need a valid token) is read, and the caller's email address is extracted and returned.

Fortunately, the following blog post by paul.todd1  will assist you greatly in this regard:

How to get the email of the logged-in user in Cloud Foundry


 

Motivation:

 The information in Neo Environment about the currently logged-in user is simple to access, appropriate, and accurate enough for its intent. However, the appropriateness and importance of the information we receive in our CF Account is not for its intended intent.

JWTs are by-value tokens. This indicate that they are data-rich. Even if you can’t see the information through your own eyes, it’s always there and easily accessible. Whether or not this is an issue is determined by the token’s intended audience.

We can start using the data from the JWT in our applications this isn't an issue in and of itself, but it can quickly escalate if we try to alter the structure of the data in our JWT. Many integrating apps can suddenly stop working because they are not prepared for the new structure (e.g. some field missing, or change to max length of the field).

Taking these into consideration In this post, I'd like to share my work on how we can obtain logged-in USER Details in SAP CLOUD PLATFORM(CF Environment) using User Account and Authentication (UAA) Service APIs as seen in the image below.


 

Prerequisites


You need to have:

  1. A valid SAP Cloud platform account if not please follow Get a Free Account on SAP BTP Trial

  2. The Cloud Foundry command-line tools installed if not please follow Install the Cloud Foundry Command Line Interface (CLI)

  3. Editor of your choice (I use VS-code)

  4. Download the latest version of Node.js.(I personally use node v12.0.0)


A complete source code is available over here.

Let’s proceed step by step

Step 1:  Create your application


Create a new dedicated directory for your Node.js application called “cf-userinfo” and another directory inside it called “app”.
% mkdir cf-userinfo
% mkdir cf-userinfo/app

To start the application setup, change to the “app” directory and execute “npm init” in the command line. This will walk you through creating a package.json file.
% cd cf-userinfo/app
% npm init

Once the above command executed command line will ask you to provide some information to initialize your packge.json file inside your project folder. An important field is a name which you can provide “cf-userinfo”
package name: (cf-userinfo)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)

Now that we have initialized the project. Let’s install the app-route package using the following command:
% npm install @sap/approuter

After a couple of minutes, the package will successfully be installed and your package.json file should look like as below

Create a script file js under a directory called “app” and paste the below JavaScript code to obtain the currently logged-in user detail.
const approuter = require("@sap/approuter");
const request = require("request");
let ar = approuter();
ar.beforeRequestHandler.use("/userinfo", (req, res) => {
if (!req.user) {
res.statusCode = 403;res.end("Missing JWT Token");
}
var options = {
method: "GET", url: req.user.token.oauthOptions.url+"/userinfo",
headers: { Authorization: "Bearer " + req.user.token.accessToken,},
};
request(options, function (error, response) {
if (error) {
res.statusCode = 500;res.end("unavailable user information");
};
res.end(response.body);
});
});
ar.start();

Update script tag in package.json
"scripts": {
"start": "node index.js",
"test": "echo \"Error: no test specified\" && exit 1"
}

Create another directory “resources” inside “app” folder for a simple HTML file called index.html. This is as basic an HTML file as possible
<html>

<body>

<h1>Index file of CF userinfo app </h1>

<a href="https://blogs.sap.com/userinfo">current user</a>

</body>

</html>

Create the xs-app.json file. The xs-app file is required to specify the routes for the app router.
{
"welcomeFile": "index.html",
"authenticationMethod": "route"
}

 

Step 2: Create XSUAA Service Instance


Create a file called xs-security.json in the main directory “cf-userinfo” and copy the following code to this file and save it.
{
"xsappname": "cfuserinfo",
"tenant-mode": "dedicated"
}

This file is used to set up the default roles and scopes for the user but it is not required for this app. Now create XSUAA service instance using this file. Let’s do this using the following command.
% cf create-service xsuaa application cf-userinfo-uaa -c xs-security.json

 

Step 3: Create deployment descriptor file


You must include the deployment descriptor file (manifest.yml) to deploy an application into Cloud Foundry. This file contains details about the applications to be deployed.
So next file we need to create is manifest.yml in the main directory “cf-userinfo” and copy the following resource requirements and save it.
---
applications:
- name: cf-userinfo
path: app
memory: 256M
random-route: true
buildpacks:
- nodejs_buildpack
services:
- cf-userinfo-uaa


 

Step 4: Deploy your app


Finally, it is time to deploy your application. Be in the same directory where you have created manifest.yml file and deploy the application using the following command:
% cf push

Use a random route created after a CF push to test your application.



How it works


The browser will establish a connection to the deployed application and verify that the user is currently logged in. If they aren't, AppRouter will log you in using the OAuth flow.

When the /userinfo path is called, the user object attached to the request contains token details that are used to call the XSUAA userinfo API and return the details of the logged-in user to the caller.
3 Comments
vfweiss
Participant
0 Kudos
Hello Lalit,

The AppRouter has an User API nowadays:
https://www.npmjs.com/package/@sap/approuter#user-api-service

I know it doesn't support all the data fields as they hardcoded a subset, but wouldn't it be more useful to extend on that in that case? Or at least use the same logic as in that, by decoding the JWT token. This saves a call to the UAA service, but still holds all the data.

Kind regards,

Vincent
lalitmohan
Product and Topic Expert
Product and Topic Expert
0 Kudos
Hello Vincent,

Thank you for your feedback. it's good to know that AppRouter now has a USER API, which will undoubtedly be more useful for the appropriate use case. I recognize that the JWT access-token contains all of the data, but we have no way of knowing how important this data is after risking decoding it. We can save a UAA service call, but when validating JWT, make sure it's being used correctly.

Best Regards,

Lalit
Jay2
Product and Topic Expert
Product and Topic Expert
0 Kudos
Thank you Lalit for sharing.