Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
balbino_soaresferreirafil
Active Participant
In this blog post, my intent is to try to explain more about authentication strategies on SAP Cloud Platform, using Sap Cloud Application Programming Model with Node.js and Multi-Target Application Deployment.

In this link, you can found a guide about authentication while accessing CDS services in Node.js applications. https://cap.cloud.sap/docs/node.js/authentication#jwt

First, I want to explain a little bit about the authentication flow and the project structure.

Multi-Target Application Project


Normally, an application on SAP Cloud Platform will consist of several parts, that will be deployed as separate applications. Each one of these applications will be a module of your project. This structure is the base of the Multi-Target Application Model.

In this model, we have a deployment descriptor file, the mta.yaml. This file is responsible to define each part of your project, the resources necessary to execute this project, and the connection link between their modules.

In this module, we have a mtar file with the entire project and the deployment descriptor file defines how the resources and services must be created and allocated.

To be able to build your project with a multi-target application and deploy him using cloud foundry command line (CF CLI), some tools and steps will be necessary:

  1. If you don’t have a Cloud Foundry Subaccount on SAP Cloud Platform yet, create your Trial Account;

  2. The Cloud MTA Build Tool (MBT) is installed;

  3. Download and install the cf command-line client for Cloud Foundry;

  4. Install MultiApps CF CLI Plugin;

  5. Log on to Cloud Foundry, using cf login to your trial account;


To build an MTA application you will need to execute this command. You can define a script in your package.json if you prefer.
cds build/all --clean && mbt build -p=cf

User authentication in the MTA Project


In SAP Cloud Platform we have a service that is responsible to do the authentication stuff, this service is the XSUAA service (Authorization & Trust Management). So, to use authentication in your application you will need to create a service instance of the XSUAA service and link this service to your application's services.

In an MTA project, we can do it in mta.yaml file. See the example below, where we defined the resource to be allocated using the XSUAA service.

 
##############  RESOURCES  ##################################      
resources:
- name: school-db-hdi-container
parameters:
service: hanatrial
service-plan: hdi-shared
type: com.sap.xs.hdi-container
properties:
hdi-container-name: ${service-name}
### XSUAA service instance
- name: school-xsuaa
parameters:
path: ./xs-security.json
service: xsuaa
service-plan: application
service-keys:
- name: school-xsuaa-key
type: com.sap.xs.uaa
############################################################

Authentication Flow


In general, the entire application will be formed of a database module, responsible for the database content, a module for the service layer, in our case this module will be a Node.js application and a finally, a user interface module that will be the entry point of the entire application.

All application that uses an XSUAA service needs a module responsible for the application router. Generally, this module is the "app" module or the UI module and it will be the entry point of your application. But even your application doesn’t have a UI interface, you will need to create an app to be responsible for the application router.

When your business user accesses the application UI using the browser, the application router redirects the browser to the UAA service, where your user needs to authenticate. After successful authentication, the UAA sends the browser back to applications router with an OAuth authorization code. Now the application router sends this authorization code to the UAA directly, this time not by browser, to exchange it into on OAuth access token. If the access token is obtained successfully, your users will be logged on to the UI part of the application. This token needs to be passed to the Node.js application part, to grant the privileges defined in CDS service.

To enable your UI to pass this authentication on to the node.js application part, you need to ensure that the destination to your node.js application part is configured such that the access token is sent. It is configured in mta.yaml file by the property in the "destination" group of the app-router. The property is forwardAuthToken": true.

See below the configuration of the app-router in mta.yaml file.
#### App Router used to authentication          
- name: school-app-router
type: nodejs
path: app
build-parameters:
ignore: ["node_modules/"]
parameters:
disk-quota: 256M
memory: 256M
requires:
- name: school-xsuaa
- name: srv_api
group: destinations
properties:
forwardAuthToken: true
strictSSL: false
name: srv_api
url: ~{url}

 

The same XSUAA service needs to be bound to the SRV app and to the app-router, in the mta.yaml. See the "requires" part on the SRV app configuration.
#### The SRV Module is the backend of application, It will be started      
- name: school-srv
type: nodejs
path: srv
build-parameters:
ignore: ["node_modules/"]
parameters:
memory: 256M
disk-quota: 256M
provides:
- name: srv_api
properties:
url: ${default-url}
requires:
- name: school-db-hdi-container
- name: school-xsuaa

As said earlier, is necessary to include and configure the app-router in your application even if you only have a backend service. But If you have a UI app in your project you can configure the router in this UI module.

The important file in this part is the xs-app.json responsible to create the routes and authentication method that will be used. In the example above see that access in any URL will be redirected to XSUAA because the authentication method is set to the route. After the authentication is successful the route will redirect to the destination srv_api, which is the service defined in mta.yaml file.

Below an example of the xs-app.json file.
{
"authenticationMethod":"route",
"routes": [
{
"source": "^/(.*)$",
"target": "$1",
"authenticationType": "xsuaa",
"destination": "srv_api",
"csrfProtection": false

}
]
}

Step to Step to configure XSUAA in your application.


For this flow works as expected is necessary to do some configurations in your application. And this can be done by the following steps:

You can see an entire project of example in my GitHub: https://github.com/balbinosoares/school-cap.

  1. In your service.cds file define the annotations to require the authentication with a specified role, for example in my AdminServices, it requires the role admin. For more information about this topic check https://cap.cloud.sap/docs/guides/authorization.
    service AdminService  @(requires:'admin'){​


  2. Generate the xs-security.json file. This file defines the role-template of the application and is used by the XSUAA service. It can be generated by cds compile, using as reference the annotations defined in the services model.
    cds compile srv/ --to xsuaa > .xs-security.json

    {
    "xsappname": "school",
    "tenant-mode": "dedicated",
    "scopes": [
    {
    "name": "$XSAPPNAME.admin",
    "description": "admin"
    }
    ],
    "attributes": [],
    "role-templates": [
    {
    "name": "admin",
    "description": "generated",
    "scope-references": [
    "$XSAPPNAME.admin"
    ],
    "attribute-references": []
    }
    ]
    }


  3. Install the modules that are required at runtime to authenticate the user and read the token. You need to install these modules both in the root of your project and in the SRV folder of your project.
    npm install --save passport @sap/xssec @sap/xsenv

    Below you can see the Package.json of the SRV module.
    {
    "name": "school-srv",
    "description": "Generated from ../package.json, do not change!",
    "version": "1.0.0",
    "dependencies": {
    "@sap/cds": "^3.21.2",
    "@sap/xsenv": "^2.2.0",
    "@sap/xssec": "^2.2.5",
    "express": "^4.17.1",
    "hdb": "^0.17.1",
    "passport": "^0.4.1"
    },
    "engines": {
    "node": "^8.9",
    "npm": "^6"
    },
    "devDependencies": {},
    "scripts": {
    "postinstall": "npm dedupe && node .build.js",
    "start": "node ./node_modules/@sap/cds/bin/cds.js serve gen/csn.json",
    "watch": "nodemon -w . -i node_modules/**,.git/** -e cds -x npm run build"
    },
    "cds": {
    "requires": {
    "db": {
    "kind": "hana",
    "model": "gen/csn.json"
    }
    },
    "auth": {
    "passport": {
    "strategy": "JWT"
    }
    }
    }
    }

    And next, the Package.json of the top-level package.
    {
    "name": "school",
    "version": "1.0.0",
    "description": "A project to pratice and study more about SAP Cloud Application Programming Model. ",
    "repository": "https://github.com/balbinosoares/school-cap.git",
    "license": "Apache-2.0",
    "dependencies": {
    "@sap/cds": "^3.21.x",
    "@sap/hana-client": "^2.4.182",
    "@sap/xsenv": "^2.2.0",
    "@sap/xssec": "^2.2.5",
    "express": "^4.17.1",
    "hdb": "^0.17.1",
    "passport": "^0.4.1"
    },


  4. Create the App-router of your application.

    • Create an app folder

    • Create a file: Package.json in /app
      {
      "name": "approuter",
      "dependencies": {
      "@sap/approuter": "latest"
      },
      "scripts": {
      "start": "node app.js"
      }
      }


    • Create an xs-app.json file.
      {
      "authenticationMethod":"route",
      "routes": [
      {
      "source": "^/(.*)$",
      "target": "$1",
      "authenticationType": "xsuaa",
      "destination": "srv_api",
      "csrfProtection": false

      }
      ]
      }


    • Create a mta.yaml file;
      ID: school
      _schema-version: "2.1"
      version: 0.0.1
      parameters:
      enable-parallel-deployments: true
      ############## MODULES ##################################
      modules:
      #### We can see that module name DB is created as application, it will be in a stopped state most of the time, it is used only during deployment for HDB modules.
      - name: school-db
      type: hdb
      path: db
      build-parameters:
      ignore: ["node_modules/"]
      parameters:
      memory: 256M
      disk-quota: 256M
      requires:
      - name: school-db-hdi-container
      #### The SRV Module is the backend of application, It will be started
      - name: school-srv
      type: nodejs
      path: srv
      build-parameters:
      ignore: ["node_modules/"]
      parameters:
      memory: 256M
      disk-quota: 256M
      provides:
      - name: srv_api
      properties:
      url: ${default-url}
      requires:
      - name: school-db-hdi-container
      - name: school-xsuaa
      #### App Router used to authentication
      - name: school-app-router
      type: nodejs
      path: app
      build-parameters:
      ignore: ["node_modules/"]
      parameters:
      disk-quota: 256M
      memory: 256M
      requires:
      - name: school-xsuaa
      - name: srv_api
      group: destinations
      properties:
      forwardAuthToken: true
      strictSSL: false
      name: srv_api
      url: ~{url}
      ############## RESOURCES ##################################
      resources:
      - name: school-db-hdi-container
      parameters:
      service: hanatrial
      service-plan: hdi-shared
      type: com.sap.xs.hdi-container
      properties:
      hdi-container-name: ${service-name}
      ### XSUAA service instance
      - name: school-xsuaa
      parameters:
      path: ./xs-security.json
      service: xsuaa
      service-plan: application
      service-keys:
      - name: school-xsuaa-key
      type: com.sap.xs.uaa
      ############################################################




  5. Now you can build the application mtar file. To Build the mta file execute this command:
    cds build/all --clean && mbt build -p=cf"​


  6. And finally, deploy the app on Cloud Foundry.
    cf deploy mta_archives/school_0.0.1.mtar​



The NPM Modules used in the authentication process


@Sap/xssec: XS Advanced Container Security API for node.js


This module is responsible for authentication for node applications in XS Advanced relies on a special usage of the OAuth 2.0 protocol, which is based on central authentication at the UAA server that then vouches for the authenticated user's identity via a so-called OAuth Access Token. The current implementation uses as access token a JSON web token (JWT), which is a signed text-based token following the JSON syntax.

@Sap/xsenv


Utility for easily reading application configurations for bound services and certificates in the SAP Cloud Platform Cloud Foundry environment, SAP XS advanced model and Kubernetes (K8S).

References


MTA Model: https://www.sap.com/documents/2016/06/e2f618e4-757c-0010-82c7-eda71af511fa.html

Cloud MTA Build Tool: https://sap.github.io/cloud-mta-build-tool/

Authentication in CAP Projects https://cap.cloud.sap/docs/node.js/authentication
8 Comments
Labels in this area