Fundamentals of Security in BTP: Implement Authentication in a Node.js App

This blog series is mainly targeted for developers and administrators. If you are someone who has gone through the plethora of tutorials, documentation, and presentations on security topics in SAP BTP and still lacks the confidence to implement security for your application, you have come to the right place.

In this blog series, you will learn:

  • How to protect an app in SAP BTP, Cloud Foundry environment from unauthorized access
  • How to implement role-based features
  • How SAP Identity Provider and Single-sign-on works

For ease of reading, I have split this in multiple blogs, which are:

  1. Fundamentals of Security in BTP: Introduction Part 1
  2. Fundamentals of Security in BTP: Introduction Part 2
  3. Fundamentals of Security in BTP: OAuth Concept (optional)
  4. Fundamentals of Security in BTP: Implement Authentication in a Node.js App [current blog]
  5. Fundamentals of Security in BTP: Implement Authorization in a Node.js App

So far, we have learnt about the core concepts. Now, let’s get our hands dirty by implementing the authentication.

  • We will first deploy an unsecured Node.js Hello World in BTP, Cloud Foundry
  • Further, we will implement authentication in the application

Note: Although, you can use any other IDE or command line interface to develop and deploy the Node.js app, we will recommend you use SAP Business Application Studio.

If you are new to SAP Business Application Studio, you may go through this tutorial to learn how to use it.

I have saved a simple Node.js hello world application in GitHub. Follow below steps to deploy it to Cloud Foundry environment of BTP.

  1. Open Business Application Studio. Go to Terminal -> New Terminal and run below command.

                      git init

                      git clone https://github.com/rajagupta20/unsecured-nodejs-app.git

  1. Click on Open Folder and select the application folder (unsecured-nodejs-app). Check below files.

start.js file – has basic hello world code

 

manifest.yml file – has runtime configurations

Execute the command cf push to deploy to your cloud foundry space and try to access the app.

Result

You should be able to access the application without any authentication required.

Let’s quickly recap what we learnt in previous blogs.

  • business user wants to access your application.
  • The single point of entry is the application router.
  • The application router sends the request to XSUAA.
  • The XSUAA further forwards the request to Identity Provider, which takes care of authentication.

To implement authentication, all we need to do is:

  1. Implement App Router
  2. Create an instance of XSUAA service
  3. Bind the application and App Router with XSUAA instance
  4. Modify the application to make sure it only accepts request contains a JWT token

I have saved completed project in Github. Let’s clone that and go through above 4 points.

Clone the final project from GitHub by running below commands:

                   git init

                   git clone https://github.com/rajagupta20/secured-nodejs-app-demo1.git

 

Let’s go through these 4 tasks one by one.

Remember – technically, Application Router is a Node.js App, available in public in NPM.

To add an App Router in our application, all we need to do is:

  1. Create a folder (say approuter)
  2. Create a json file inside the folder
  3. In package.json file – add the dependency on Approuter and configure its start point
  4. Create another file called xs-app.json inside approuter folder to configure the App Router

Check the cloned application and look into these 2 files.

package.json

xs-app.json

xs-app.json (Routing Configuration File)

App Router’s configuration is defined in the file called xs-app.json. In this example, we are keeping it simple by just adding a route. The route says – If the response URL pattern matches the given regex expression, forward it to a destination (here myapp).

The destination (myapp) and App Router (approuter1) is specified in manifest.yml file as shown below.

Note: Later we will look into xs-app.json file in detail.

Before creating an instance of XSUAA, you need an important file called xs-security.json.

xs-security.json (Application Security Descriptor)

You may have noticed a file called xs-security.json in the cloned project.

xs-security.json is the file which defines the details of the authentication methods and authorization types to use for access to your application.

The xs-security.json file uses JSON notation to define the security options for an application. The information in this file is used at application-deployment time, for example, to create required roles for your application.

In this example, we are making it extremely simple, by just specifying xsappname and tenant-mode.

  • xsappname property specifies the name of the application that the security description applies to.
  • tenant-mode can be “dedicated” for single-tenant application and “shared” for multitenant application

Note: Later we will look into xs-security.json in detail. You may also check the help document.

Create instance of XSUAA using xs-security.json file

There are different ways to create an instance of XSUAA. Major options are:

  1. Go to BTP Cockpit -> Subaccount -> Space -> Instance -> Create as shown below

  1. Use command line tool. Execute below command

      cf create-service xsuaa application <service_instance_name> -c xs-security.json

  1. In case of Multitarget Applications (MTA), use configurations specified in yml file, which automatically creates XSUAA instances and bind it with applications. This is the most preferred way, and we will look into it later.

To make sure we understand what’s happening behind the scenes, let’s use command approach. Executing below command:

          cf create-service xsuaa application nodeuaa -c xs-security.json

Here nodeuaa is the XSUAA instance name.

3. Bind the XSUAA instance with application and App Router

We can specify the binding of XSUAA instance with application and app router in manifest.yml file as shown below.

You can check the XSUAA instance and binding status in BTP cockpit as shown below.

Finally, we need to make sure that application entertain only authenticated request containing a valid JWT token. In Node.js we can do that by using passport module.

That’s it. We have implemented the authentication in our Node.js application.

Execute cf push command to deploy the application. It will deploy both app router and application. You can check them in the BTP cockpit.

Try to access the application (“myapp-secured-demo1”) directly. It would give “Unauthorized” error.

Now, try to access the application via app router, it will first redirect to Identity Provider and once authenticated (either using username/password or certificate-based login), it redirects to application. Below image shows the call flow if SAP ID Service is used as Identity Provider.

I hope now you got overall idea on how authentication works. In the next blog, we will cover how to implement authorization.

If you have any question, let me know in the comment.

Next blog in the series:

  • Fundamentals of Security in BTP: Implement Authorization in a Node.js App (To be published)