Skip to Content
Technical Articles

SAP Cloud Foundry – Authentication mechanism for NodeJS and XSJS APIs

The User Account and Authentication service (UAA) is used for user authentication and authorization. Mode details at [link]. More details regarding UAA can be found at [link]

We are going to make use of the application service plan. More details about the service plans can be found on the SCP Cockpit:

In this article we are going to add passport authentication to our earlier developed NodeJS webservice. We will look at how to authenticate the calls to our webservice, create user roles and test the API.

  1. Create a XSUAA service as below:

    Select XSUAA service, select the plan as application:
  2. Create a xs-security.json file and add your custom roles. In the next blog we also look at reading these roles using NodeJS APIs. You can skip this step as well. Add the below details:
    {
      "xsappname": "routingMTA",
      "tenant-mode": "dedicated",
      "description": "Security profile of called application",
      "scopes": [
        {
          "name": "uaa.user",
          "description": "UAA"
        },
        {
          "name": "$XSAPPNAME.USER",
          "description": "User role"
        },
        {
          "name": "$XSAPPNAME.ADMIN",
          "description": "Admin role"
        }
      ],
      "role-templates": [
        {
          "name": "Token_Exchange",
          "description": "UAA",
          "scope-references": [
            "uaa.user",
            "xs_authorization.read"
          ]
        },
        {
          "name": "READ_USER",
          "description": "Read user Role",
          "scope-references": [
            "uaa.user",
            "$XSAPPNAME.USER"
          ]
        },
        {
          "name": "ADMINISTRATOR",
          "description": "Admin Role",
          "scope-references": [
            "uaa.user",
            "$XSAPPNAME.ADMIN"
          ]
        }
      ]
    }​

    We have added two custom roles as well. USER and ADMINISTRATOR. We use these roles to provide restrictions to APIs and data fetched by these APIs.

  3. Add the xs-security.json file to the XSUAA instance created:
  4. Add the XSUAA instance to NodeJS module in the yaml file:
  5. Now to authenticate the calls we need to include the passport authentication and add UAA configuration to xsjs calls. We do this in the initialize.js file. Replace the initialize.js file contents with below code:
    /*eslint no-console: 0, no-unused-vars: 0*/
    "use strict";
    module.exports = {
    initExpress: function() {
    		var xsenv = require("@sap/xsenv");
    		var passport = require("passport");
    		var xssec = require("@sap/xssec");
    		var express = require("express");
    
    		//Initialize Express App 
    		var app = express();
    		
    		//Add passport authentication and initialize
    		passport.use("JWT", new xssec.JWTStrategy(xsenv.getServices({
    			uaa: {
    				tag: "xsuaa"
    			}
    		}).uaa));
    		app.use(passport.initialize());
    		app.use(
    			passport.authenticate("JWT", {
    				session: false
    			})
    		);
    		
    		return app;
    	},
    
    initXSJS: function(app) {
    var xsjs = require("@sap/xsjs");
    var xsenv = require("@sap/xsenv");
    var options = {
    	anonymous : true, 
    	auditLog : { logToConsole: true }, // Required. change to auditlog service for productive scenarios
    	redirectUrl: "/index.xsjs",
    	xsApplicationUser: false, //Important
    	context: {
    		base: global.__base,
    		env: process.env,
    		answer: 42
    	}
    };
    
    // configure UAA
    try {
    	options = Object.assign(options, xsenv.getServices({
    		uaa: {
    			tag: "xsuaa"
    		}
    	}));
    } catch (err) {
    	console.log("[WARN]", err.message);
    }
    
    // start server
    var xsjsApp = xsjs(options);
    app.use(xsjsApp);
    }
    };​
  6. Add the dependencies to package.json file:
    "dependencies": {
      "cfenv": "latest",
      "passport": "0.4.0",
      "@sap/xssec": "latest",
      "express": "4.17.1",
      "@sap/xsenv": "^2.0.0",
      "@sap/xsjs": "^5.2.0",
      "@sap/cds": "^2.10"
    }
  7. Build your project and run as NodeJS Application.Test the NodeJS API for authentication. Run the webservice. We get the unauthorized error if everything is set properly.
  8. On SCP Cockpit navigate to “Authorization & Trust Management” service section. Select the uaa instance name which we created earlier. We can see the clientid and clientsecret mentioned. We use this to test our API via REST calls.
  9. In Advanced REST Client select POST method. Add the url mentioned in the above screenshot.Add additional parameters to your URL as:
    https://xxx.authentication.xxxx.hana.ondemand.com/oauth/token?grant_type=password&username=test.user@test.com&password=testing@123

    The URL consists of grant_type as password, username as password of the cockpit user.Add authorization header. Add the client ID and Client secret as the Id and Password.
    Perform “SEND” and the url will fetch us the “access_token”.

  10. Now that we have our access token, we can proceed with our testing.Pass the token in the authorization header, perform GET call:
    We have successfully received response from node API. Now we are calling the xsjs API  below:

We have successfully tested the authentication mechanism for our NodeJS module. In the further blog we will see how we can read the roles defined in the xs-security.json file. We will implement a user role API call to read the roles assigned to a user.

 

Thanks,
Mayur

 

 

Be the first to leave a comment
You must be Logged on to comment or reply to a post.