Authentication and Authorization CAP App BAS Cloud Environment
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:
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 service-aut](https://aracelychavez.com/wp-content/uploads/2021/03/service-aut.png)
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 package_json_aut](https://aracelychavez.com/wp-content/uploads/2021/03/package_json_aut.png)
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 package_json_dep](https://aracelychavez.com/wp-content/uploads/2021/03/package_json_dep.png)
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 create_mta](https://aracelychavez.com/wp-content/uploads/2021/03/create_mta.png)
Seleccionar Approuter Configuration y luego Start.
![approuter1 approuter1](https://aracelychavez.com/wp-content/uploads/2021/03/approuter1.png)
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 approuter2](https://aracelychavez.com/wp-content/uploads/2021/03/approuter2.png)
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 package_json_app](https://aracelychavez.com/wp-content/uploads/2021/03/package_json_app.png)
Modificar el archivo xs-app.json dentro del directorio creado.
{
"authenticationMethod": "route",
"routes": [
{
"source": "^/(.*)",
"destination": "srv-api"
}
]
}
![xs-app_json xs-app_json](https://aracelychavez.com/wp-content/uploads/2021/04/xs-app_json.png)
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_cap6](https://aracelychavez.com/wp-content/uploads/2021/03/template_cap6.png)
![template_cap7 template_cap7](https://aracelychavez.com/wp-content/uploads/2021/03/template_cap7.png)
Si todo sale bien, veremos una nueva aplicación approuter creada en el BTS cockpit.
![myappl_app myappl_app](https://aracelychavez.com/wp-content/uploads/2021/03/myappl_app-1.png)
Ejecutamos la aplicación en incognito, se nos pedirán las credenciales.
![login login](https://aracelychavez.com/wp-content/uploads/2021/03/login.png)
Seleccionamos cualquier entidad, por ejemplo Books.
![endpoint endpoint](https://aracelychavez.com/wp-content/uploads/2021/03/endpoint.png)
Nos mostrará el siguiente mensaje de falta de autorización.
![unauthorized unauthorized](https://aracelychavez.com/wp-content/uploads/2021/03/unauthorized.png)
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 viewer](https://aracelychavez.com/wp-content/uploads/2021/04/viewer.png)
myappl_admin
![admin admin](https://aracelychavez.com/wp-content/uploads/2021/04/admin.png)
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 myappl_app_books](https://aracelychavez.com/wp-content/uploads/2021/03/myappl_app_books.png)
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 env1](https://aracelychavez.com/wp-content/uploads/2021/03/env1.png)
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 default-env-app](https://aracelychavez.com/wp-content/uploads/2021/03/default-env-app.png)
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 approuter_local](https://aracelychavez.com/wp-content/uploads/2021/03/approuter_local.png)
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.