Aracely Chávez
My blog
  • Home
  • FAQ
  • Blog
  • Contacto
auto
March 27 2021

Authentication and Authorization CAP App BAS Cloud Environment

Aracely Chavez SAP BAS, CAP, Cloud Foundry, Node Js

Agregar autenticación y autorización a una aplicación con el modelo de programación CAP (Cloud Application Programming) en el ambiente de desarrollo BAS (Business Application Studio) en la nube. 

Prerequisitos: 

  • Una cuenta trial SAP Cloud BTP.
  • Subscripción al Business Application Studio (y estar firmados a Cloud Foundry). 
  • DB de espacio de desarrollo este en estatus RUNNING.
  • Crear una aplicación Node.js usando Cloud Application Programming Model.

Conceptos básicos:

En CAP hay dos tipos de estrategias de autentificación y autorización. 

  • Mock: Usado solo para entorno de desarrollo para probar las autorizaciones en modo “dummy”. Con solo el paso 1 y 2 ya se podrían probar las autorizaciones configuradas en el servicio.
  • JWT: Usado para productivo, el cual necesita ciertas configuraciones de servicios y keys. A partir del paso 3 las pruebas apuntaran solo a esta estrategia. 

1.- Adecuar el servicio para agregar autentificación y autorización.

Agregar autentificación y autorización requerida al servicio. En este caso es requerida la autentificación, el rol viewer y en el caso de la entidad ordenes se deberá tener el rol admin. 

service-aut

2.- Instalar dependencias de Autentificación y Autorización.

Hacemos las siguientes modificaciones al archivo package.json.

Si no queremos probar la autentificación dummy, solo agregar lo que está en negritas.

    "cds": {
         "requires": {
            "[production]": {
                "uaa": {
                    "kind": "xsuaa"
                }
            },
            "auth": {
                "[production]": {
                    "strategy": "JWT"
                },
                "[development]": {
                    "strategy": "mock",
                    "users": {
                        "alice": {
                            "roles": [
                                "admin",
                                "viewer"
                            ]
                        },
                        "bob": {
                            "roles": [
                                "viewer"
                            ]
                        }
                    }
                }
            },

Lo que hacemos es agregar la estrategia para la autentificación y autorización por ambiente. 

package_json_aut

Ahora instalamos esas dependencias para la autentificación y autorización. 

npm install -save passport @sap/xssec @sap/xsenv @sap/audit-logging

El archivo package.json ha quedado adecuado con las dependencias registradas.

package_json_dep

Por default hay usuarios dummy, en este caso, alice y bob (sin password) se agregaron como usuarios con los roles adecuados al archivo package.json cuando se ejecuta el servicio localmente.

Si queremos saber las autorizaciones dummy desde la terminal ejecutamos:

cds env get requires.auth

En este punto ya se puede probar las autorizaciones configuradas con los usuarios dummy.

npm start

Nota: Borrar los datos locales del navegador cada vez que deseamos usar un nuevo usuario. 

A continuación la configuración para probar la estrategia JWT.

3.- Probar estrategia JWT (configuración de APPROUTER).

En una terminal ejecutamos el siguiente comando:

cds compile srv/ --to xsuaa > xs-security.json

Esto crea el archivo xs-security.json con todos los roles de seguridad requeridos.

Solo si estamos desde el BAS se requiere agregar el código en rojo. 

{
  "xsappname": "myappl",
  "tenant-mode": "dedicated",
  "scopes": [
    {
      "name": "$XSAPPNAME.viewer",
      "description": "viewer"
    },
    {
      "name": "$XSAPPNAME.admin",
      "description": "admin"
    }
  ],
  "attributes": [],
  "role-templates": [
    {
      "name": "viewer",
      "description": "generated",
      "scope-references": [
        "$XSAPPNAME.viewer"
      ],
      "attribute-references": []
    },
    {
      "name": "admin",
      "description": "generated",
      "scope-references": [
        "$XSAPPNAME.admin"
      ],
      "attribute-references": []
    }
  ],
  "oauth2-configuration": {
    "redirect-uris": [
        "https://*.applicationstudio.cloud.sap/**"
  ]}
}

Ahora hay que agregar un módulo de approuter al archivo MTA, seleccionar el archivo y dar click al botón derecho del mouse, seleccionar la opción Create MTA Module from template. 

create_mta

Seleccionar Approuter Configuration y luego Start. 

approuter1

En HTML5 application runtime seleccionar Standalone Approuter. 

Si se selecciona Yes en Add authentification, se creará el archivo xs-security.json,  como ya se había creado seleccionar No.

Seleccionar No en Do you want to add a UI? ya que solo probaremos la autentificación del servicio.

approuter2

En el archivo package.json dentro del directorio creado modificamos la dependencia a la versión 9.1

{
	"name": "myappl-app",
	"description": "Node.js based application router service",
	"engines": {
		"node": "^8.0.0 || ^10.0.0"
	},
	"dependencies": {
		"@sap/approuter": "9.1"
	},
	"scripts": {
		"start": "node node_modules/@sap/approuter/approuter.js"
	}
}
package_json_app

Modificar el archivo xs-app.json dentro del directorio creado.

{
  "authenticationMethod": "route",
  "routes": [
{ "source": "^/(.*)", "destination": "srv-api" } ] }
xs-app_json

Renombro el direcctorio myappl-approuter por app (opcional), y hago el cambio de nombre dentro del MTA, así como verificamos el módulo approuter y la referencia al archivo xs-security.json

## Generated mta.yaml based on template version 0.4.0
## appName = myappl
## language=nodejs; multiTenant=false
## approuter=
_schema-version: '3.1'
ID: myappl
version: 1.0.0
description: "A simple CAP project."
parameters:
  enable-parallel-deployments: true
   
build-parameters:
  before-all:
   - builder: custom
     commands:
      - npm install --production
      - npx -p @sap/cds-dk cds build --production

modules:
   # --------------------- APP MODULE ------------------------
 - name: myappl-app
 # ------------------------------------------------------------
   type: approuter.nodejs
   path: app
   parameters:
     disk-quota: 1024M
     memory: 256M
   requires:
    # Resources extracted from CAP configuration
    - name: myappl-uaa
    - name: srv-api
      group: destinations
      properties:
        name: srv-api
        url: '~{url}'
        timeout: 60000
        forwardAuthToken: true

 # --------------------- SERVER MODULE ------------------------
 - name: myappl-srv
 # ------------------------------------------------------------
   type: nodejs
   path: gen/srv
   parameters:
     disk-quota: 1024M
     memory: 256M
   properties:
     EXIT: 1
   requires:
    # Resources extracted from CAP configuration
    - name: myappl-db
    - name: myappl-uaa
   provides:
    - name: srv-api      # required by consumers of CAP services (e.g. approuter)
      properties:
        url: ${default-url}

 # -------------------- SIDECAR MODULE ------------------------
 - name: myappl-db-deployer
 # ------------------------------------------------------------
   type: hdb
   path: gen/db  
   parameters:
     buildpack: nodejs_buildpack
     disk-quota: 1024M
     memory: 256M
   requires:
    # 'hana' and 'xsuaa' resources extracted from CAP configuration
    - name: myappl-db
    - name: myappl-uaa


resources:
 # services extracted from CAP configuration
 # 'service-plan' can be configured via 'cds.requires..vcap.plan'
# ------------------------------------------------------------
 - name: myappl-db
# ------------------------------------------------------------
   type: com.sap.xs.hdi-container
   parameters:
     service: hana  # or 'hanatrial' on trial landscapes
     service-plan: hdi-shared
   properties:
     hdi-service-name: ${service-name}
# ------------------------------------------------------------
 - name: myappl-uaa
# ------------------------------------------------------------
   type: org.cloudfoundry.managed-service
   parameters:
     service: xsuaa
     service-plan: application  
     path: ./xs-security.json
     config:
       xsappname: myappl-${space}    #  name + space dependency
       tenant-mode: dedicated

En este punto ya podemos hacer el build y deploy, con ayuda del archivo MTA.

template_cap6
template_cap7

Si todo sale bien, veremos una nueva aplicación approuter creada en el BTS cockpit. 

myappl_app

Ejecutamos la aplicación en incognito, se nos pedirán las credenciales. 

login

Seleccionamos cualquier entidad, por ejemplo Books. 

endpoint

Nos mostrará el siguiente mensaje de falta de autorización.

unauthorized

Esto es porque aún nos falta crear los roles y asignarlos al usuario desde la cuenta trial BTP cockpit.

En el BTP cockpit creamos los roles collections y los agregamos a nuestra cuenta. 

myappl_viewer

viewer

myappl_admin

admin

Ya con los roles en el usuario volvemos a probar la aplicación app en incógnito. 

Seleccionar alguna entidad, deberá traer información desde hana.

myappl_app_books

4.- Probar localmente la aplicación

Para probar localmente necesitamos crear el archivo default-env.son tanto en el root del proyecto como en el directorio del approuter y simular productivo con la variable NODE_ENV.

Crear el archivo env-default.json en el directorio root del proyecto. 

{
  "VCAP_SERVICES": {
 "xsuaa": [
   {
     "name": "myappl-uaa",
     "label": "xsuaa",
     "tags": [ "xsuaa" ],
     "credentials": {
       [...]
     }
   }
 ]
  }
}

Las credenciales de acceso las localizamos en la opción Environmental Variables en la aplicación del servicio (tiene que estar activo) dentro del BTP Cockpit.

Copiar toda la información correspondiente a VCAP_SERVICES. 

env1

Copiar el archivo default-env.json al directorio /app. Y se le agrega además las siguientes líneas: 

    "destinations": [
        {
            "name": "srv-api",
            "url": "http://localhost:4004",
            "forwardAuthToken": true,
            "strictSSL": false
        }
    ],
default-env-app

Ahora cambiamos el script en package.json para que al hacer la prueba considere la estrategia JWT, de lo contrario se activará la estrategia mock.

"scripts": {
  "start": "NODE_ENV=production cds run"
}

Si estamos en VSC windows, en una terminal cmd asignamos la variable de ambiente:

set NODE_ENV=production

En una terminal en el root del proyecto, ejecutar la aplicación.

npm start

Dejamos expuesto el puerto http://localhost:4004/

En otra terminal pasamos al directorio /app donde ejecutamos ahí también la aplicación.

npm start

Luego exponemos el puerto http://localhost:5000/

Aparece datos del servicio, en este caso seleccionamos la entidad books. 

approuter_local

Conclusión

Lo que hicimos fue probar desde una aplicación el servicio protegido con autentificación y rol. En este caso el approuter solicitó la autentificación al usuario antes de mostrar los datos del servicio. 

 

Fin.

Photo by Markus Spiske on Unsplash

UI for Node.Js app using Fiori Annotations BAS Cloud Environment Destination using CAP service on BAS Cloud Environment

Related Posts

SAP

Vue and React Apps using SAP ES5 Gateway on BAS

clear_code

SAP

SAP Fiori Standalone App using Northwind OData Service

SAP

Sybase License SAP NetWeaver AS ABAP

About me

Hola, me llamo Ara,  soy Ingeniera en Sistemas y SAP Sr. Consultant. Escribo acerca de tecnologías SAP en español. Networking: contáctame.

Newsletter

Categories

  • Programming
  • SAP
  • Web Design

Recent Posts

  • dean-pugh-lap-winEjercicio en PSEINT
    October 22, 2022
  • Vue and React Apps using SAP ES5 Gateway on BAS
    July 17, 2021
  • clear_codeSAP Fiori Standalone App using Northwind OData Service
    May 15, 2021

Tags

ABAP BAS Bitnami CAP Cloud Foundry Connectivity Database Explorer Destinations DEVELOPER Dominio ES5 Gateway FIORI GIT repository Google.Domains HANA Hosting HTML5 Launchpad MINISAP NetWeaver Node Js Northwind Open Guided Development Plugins PSeInt Recursos Gratis SAP SAP Cloud SAPUI5 Security Subscriptions Temas Trial Account UI URL VSC Wordpress wp-admin
  • Home
  • FAQ
  • Blog
  • Contacto
  • Términos
  • Privacidad
  • Contacto