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.
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.
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.
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.
Seleccionar Approuter Configuration y luego Start.
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.
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"
}
}
Modificar el archivo xs-app.json dentro del directorio creado.
{
"authenticationMethod": "route",
"routes": [
{
"source": "^/(.*)",
"destination": "srv-api"
}
]
}
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.
Si todo sale bien, veremos una nueva aplicación approuter creada en el BTS cockpit.
Ejecutamos la aplicación en incognito, se nos pedirán las credenciales.
Seleccionamos cualquier entidad, por ejemplo Books.
Nos mostrará el siguiente mensaje de falta de autorización.
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
myappl_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.
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.
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
}
],
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.
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.