# Conexión a la base de datos y sesión

[← Volver al índice](../crudl.md)

## Los tres modos

Existen tres formas de conectar con la base de datos. **No se eligen por configuración: se resuelven como una cascada** en cada solicitud, y el primero que sea posible es el que se aplica.

1. **Conexión a través del proveedor de identidades.** Si la capa de autorización ya dejó una conexión abierta en `@http_context/session/idp/database`, el controlador la utiliza tal cual. La autenticación del usuario y la conexión llegan establecidas.

2. **Conexión por suplantación de identidad.** Si no hay conexión del proveedor de identidades, pero existe un identificador de sesión (`session/user/ids`) y se recibió el parámetro `ws` en la URL, se verifica la autorización del usuario y se obtiene una conexión bajo su identidad.

3. **Conexión constante.** Si ninguna de las anteriores es posible, se abre la conexión con el nombre cualificado y las credenciales fijas definidas en el punto de entrada.

Conviene tener presente que la cascada **degrada en silencio**: si no hay capa de autorización configurada, o si el token de sesión es inválido o está ausente, la solicitud no se rechaza; se atiende con el modo de conexión constante. Si su aplicación exige una sesión válida, debe hacerlo cumplir en la capa de autorización, no en CRUD-L.

## Nombre cualificado de la conexión

El nombre cualificado identifica una conexión del administrador de conexiones y se forma como `conexión@aplicación`. Si se omite el nombre de la conexión, se utiliza la predeterminada de esa aplicación.

Ejemplos:

* `miconexion_empresa1@sistemaempresarial`
* `@sistemaempresarial`
* `conexiones@miempresa/conexion1587@sistema_empresa`

Ver [Biblioteca dbr](../../Bibliotecas-de-funciones/dbr/dbr.md) para la sintaxis completa y la administración de conexiones.

### Cómo se determina

El controlador compone el nombre cualificado a partir de los parámetros de URL:

```
qname = {_connection} + "@" + {_app_group}
```

Si el resultado queda vacío o es solo `@`, es decir, si no se recibieron esos parámetros, se usa el valor de `@crudl.qname` definido en el punto de entrada.

Esto permite dos estilos:

**Conexión fija en el punto de entrada**

```
@crudl.qname = "miconexion@misistema"
```

**Conexión indicada en la URL**

```
https://midominio.com/misistema/entry-point.dkl?_app_group=misistema&_connection=miconexion&_entities_type=cliente
```

O bien, a través de una regla de `routes.map` que capture ambos valores como parámetros.

## Modo 1: proveedor de identidades

El controlador busca la conexión en:

```
@http_context/session/idp/database
```

Este miembro lo aporta la capa de autorización del sitio Web. Si está presente y no es nulo, se utiliza sin más comprobaciones y no se abre ninguna conexión adicional.

Es el modo preferente cuando el proveedor de identidades ya gestiona el ciclo de vida de la conexión.

## Modo 2: suplantación de identidad

Se activa cuando se cumplen simultáneamente dos condiciones:

* `@http_context/session/user/ids` contiene un identificador de sesión
* La URL incluye el parámetro `ws` con un identificador de espacio de trabajo

### Verificación de acceso

Antes de conectar, se comprueba que el usuario de la sesión satisfaga el manifiesto de privilegios definido en `@crudl.access_privilege`. El valor predeterminado exige pertenencia al espacio de trabajo indicado en `ws`:

```
@crudl.access_privilege = '{"access":[{"workspace":"' + @ws + '"}]}'
```

La comprobación se resuelve con `auth.checkPrivs`, que contrasta el manifiesto contra las membresías de la información de sesión del usuario. Si el usuario no pertenece al espacio de trabajo solicitado, la operación se aborta con el mensaje *Usuario no autorizado*.

Puede sustituir el manifiesto por uno más restrictivo o que atienda a roles y equipos. La estructura del manifiesto de privilegios se documenta en [el Modelo de Autorización de Acceso a Recursos](../../../api/cloud/workspaces/raam.md).

### Establecimiento de la conexión

Superada la verificación, se invoca `dbr.alter_id`, que realiza tres tareas:

1. Busca en la tabla `tuser` un usuario cuyo `userid` coincida con el identificador de usuario de la sesión. Si no existe, lo crea con una contraseña aleatoria.
2. Busca en `sys_session` una sesión activa cuyo `sys_guid` coincida con el identificador de sesión. Si no existe, la inserta apuntando al usuario anterior.
3. Devuelve una conexión reabierta con ese identificador de sesión.

De este modo, una identidad gestionada externamente queda representada por un usuario y una sesión locales en la base de datos, lo que permite que los mecanismos que dependen de la sesión funcionen con normalidad.

Tenga presente que el aprovisionamiento es automático: todo usuario que supere la verificación de acceso obtendrá un usuario local en la base de datos, creado en su primera solicitud. Ajuste `@crudl.access_privilege` en consecuencia.

Esta funcionalidad es específica del motor de base de datos y reside en `mysql.dbr.dkh`. Ver [Instalación y configuración](instalacion.md#otros-motores-de-base-de-datos).

## Modo 3: conexión constante

Si no se cumplen las condiciones anteriores, se abre la conexión con:

```
@crudl.qname   // o el nombre compuesto desde la URL
@crudl.user
@crudl.pwd
```

En este modo no hay sesión de usuario. Los permisos efectivos sobre los datos son los que el motor de base de datos concede a esas credenciales, y son idénticos para todas las solicitudes.

Un punto final que opera en modo de conexión constante no distingue quién lo invoca. Si necesita distinguirlo, use otro modo o resuelva la autorización antes de que la solicitud llegue al punto de entrada.

## Cómo llega el identificador de sesión

CRUD-L **no recupera el token de sesión por sí mismo**. Espera encontrar el miembro `session` ya construido en `@http_context`.

La cadena completa es:

1. **`auth.token()`** de `webauth.dkl` localiza el token. Busca, en orden: parámetro GET `ids`, parámetro GET `token`, cookie `__induxsoft_token`, campo `session_id` de un cuerpo `x-www-form-urlencoded`, miembros `ids` o `token` de un cuerpo JSON, encabezado `Authorization` según RFC 6750, y por último el contenido íntegro del encabezado `Authorization`. El orden y las ubicaciones son configurables mediante `@http_token_locations`. Ver [API webauth](../webauth.md).

2. **El proveedor de identidades** (`_protected/idp/default.dk`) usa ese token para recuperar la información de sesión del usuario.

3. **`auth.dk`** agrega el miembro `session` a `@http_context`.

4. **CRUD-L** lee `session/idp/database` y `session/user`.

En consecuencia, para un cliente REST lo natural es el encabezado `Authorization`, y para un navegador, la cookie. En ambos casos la resolución ocurre antes de que el controlador de CRUD-L se ejecute.

Ver [Devkron Basic Web Layer](../bwl.md) e [IDP basado en la API Web de Induxsoft](../idps.md).

## Autorización

CRUD-L no implementa autorización granular. No verifica privilegios por operación, por entidad ni por campo.

La única comprobación que realiza el marco es la verificación de acceso del modo 2, que condiciona la suplantación de identidad, no las operaciones.

Dos consecuencias que conviene tener presentes al diseñar sobre este marco:

* El controlador de autorizaciones de la BWL solo comprueba el privilegio `read`. La verificación de `write`, `plus` y `admin` corresponde a la API FSO o a capas superiores. Un punto final CRUD-L alcanzable por un usuario autenticado admitirá altas, cambios y bajas salvo que otra capa lo impida.
* Los permisos efectivos sobre los datos son, en última instancia, los que el motor de base de datos concede a la identidad de la conexión. En los modos 1 y 2 esa identidad corresponde al usuario; en el modo 3, a las credenciales constantes.

Si necesita autorización por operación, dispone de tres lugares donde implementarla: `auth.dk` del sitio Web, el `controller.dk` de la entidad, o los propios punteros de función del modelo. La función `auth.checkPrivs` de `webauth.dkl` resuelve un manifiesto de privilegios contra la información de sesión y es la herramienta natural para ello.

## Documentos relacionados

* [Instalación y configuración](instalacion.md)
* [El controlador](controlador.md)
* [API webauth](../webauth.md)
* [Devkron Basic Web Layer](../bwl.md)
* [Biblioteca dbr](../../Bibliotecas-de-funciones/dbr/dbr.md)
