Autenticación de usuarios y protección de conferencias con JWT
Mediante el uso de tokens, Jitsi confía en un proveedor externo de la autenticación de los usuarios. De esta manera es posible delegar la autenticación a una aplicación propia. Tomaremos como caso de ejemplo la integración con una Intranet de una Universidad en la cual sus Docentes tienen que iniciar sesión con usuario y contraseña. Internamente ese par puede validarse a su vez con LDAP, Active Directory, una base de datos propia o cualquier mecanismo imaginable, es irrelevante para JWT. El caso contempla los siguientes requerimientos básicos:
- Se debe crear un módulo dentro de la Intranet que permita a los usuarios, crear conferencias en Jitsi en las cuales serán moderadores.
- Los usuarios que accedan por fuera de la Intranet no podrán crear conferencias. Sólo podrán participar en conferencias creadas a través de la Intranet.
La interacción típica se da como sigue:
- Una Docente accede al sitio web de la Intranet. Ingresa nombre de usuario y contraseña.
- Internamente la Intranet valida las credenciales con su proveedor de identidad preferido, si la identidad es válida, carga la sesión de la aplicación Intranet para el usuario que pertenece a la Docente.
- La Docente ingresa a un módulo de gestión de conferencias Jitsi, desarrollado dentro de la Intranet para este propósito. Indica el nombre de la conferencia que quiere crear, por ejemplo “clase1” y presiona “crear conferencia”.
- Internamente, la Intranet toma los datos de la sesión de usuario y genera un token JWT.
- Con el token generado, la Intranet le informa una url que deberá utilizar la Docente para ingresar a la conferencia como creadora y moderadora. La url tendrá el formato: https://hostname-jitsi/clase1?jwt=<token> donde <token> será el valor del token generado en el paso anterior.
- Por su parte, la Docente deberá informar la url a sus invitados con el formato https://hostname-jitsi/clase1 .
- Cuando la Docente ingrese a la conferencia en Jitsi, dependiendo de la información contenida en el token, ingresará con sus datos precargados, como su nombre completo, su e-mail, su foto de perfil (avatar), etc.
Configuración
Para que Jitsi acepte tokens JWT generados de esta manera se debe configurar el archivo de .env del despliegue del nodo-maestro con las siguientes variables:
# habilitamos la autenticacion ENABLE_AUTH=1 # permitimos que ingresen invitados ENABLE_GUESTS=1 # autenticamos con tokens JWT AUTH_TYPE=jwt # establecemos el nombre de nuestra aplicación que generará los tokens (nuestra intranet) JWT_APP_ID=mi_intranet # establecemos el secreto de 256 bits que compartiremos con la aplicación intranet JWT_APP_SECRET=012345678901234567890123456789012 # permito que usuarios sin jwt token entren a las salas creadas por usuarios con jwt token JWT_ALLOW_EMPTY=0
Importante: si ya se está ejecutando la instancia de jitsi en el nodo maestro, recordar que al haber modificado el archivo .env, es necesario regenerar la configuración a mano de todos los componentes. Por lo tanto, se recomienda realizar un backup de los contenidos de ~/.jitsi-meet-cfg/{web/letsencrypt,transcripts,prosody,jicofo,jvb,jigasi,jibri} para luego poder replicar los cambios realizados.
Se deberá entonces, ejecutar:
rm -R ~/.jitsi-meet-cfg/* mkdir -p ~/.jitsi-meet-cfg/{web/letsencrypt,transcripts,prosody,jicofo,jvb,jigasi,jibri} docker-compose up -d
De esta manera, Jitsi ahora requerirá un JWT para la creación de conferencias.
Estructura del token JWT
El token modelo (su payload) es el siguiente:
{ "iss" : "mi_intranet", "room" : "*", "exp" : 1596239022, "sub": "meet.jitsi", "aud": "mi_intranet", "context" : { "user": { "group": "Docente", "id" : "aperez@miuniversidad.edu.ar", "name" : "Ana Pérez", "avatar":"https://api.adorable.io/avatars/285/abott@adorable.png" } } }
Campo | Descripción | Valor recomendado |
---|---|---|
iss | nombre de la aplicación | el mismo que declara Jitsi en su configuración (APP_ID). Ej: mi_intranet |
room | nombre de la sala que puede crear el usuario o “*” si puede crear cualquier nombre | nombre de sala si se quiere ser restrictivo o si la intranet generará el nombre de la sala. Si no, * |
exp | fecha de expiración del token expresado en segundos desde 1970-01-01T00:00:00Z UTC | cualquier valor posterior al momento de creación del token |
sub | nombre de dominio interno | meet.jitsi (siempre ya que depende del dns interno de Docker) |
aud | nombre de la aplicación que consume el servicio | el mismo valor que iss |
context | objeto que utiliza jitsi para determinar valores del contexto | |
[context.]user | objeto que utiliza jitsi para determinar valores del usuario en el contexto | |
[[context.]user.].group | nombre del grupo al que pertenece el usuario, sirve para estadísticas | la dependencia donde ejerce el usuario (instituto, facultad, secretaría, etc). Puede dejarse vacío |
[[context.]user.].id | identificador único del usuario en el sistema de autenticación | el e-mail institucional o el legajo de personal, etc |
[[context.]user.].name | nombre visible de la persona | el nombre completo y el apellido tal cual figura en los demás sistemas |
[[context.]user.].avatar | url del avatar (imagen representativa del usuario) | url pública a la foto de perfil (pequeña) o el logo de la institución |
Generación del token JWT
Como se describió anteriormente, el trabajo de la generación de los tokens JWT será a cargo de nuestra aplicación propia, en el ejemplo, será la Intranet de la Universidad. Básicamente los tokens JWT se distribuyen con una protección basada en criptografía. Aquí entra en juego el “secreto” establecido en la variable JWT_APP_SECRET de nuestro servicio Jitsi. Si bien no es un proceso complejo, lo mejor es nunca hacer nuestra propia criptografía y en su lugar utilizar librerías probadas. En nuestro caso, dependiendo del lenguaje de programación y las tecnologías utilizadas en el desarrollo de la aplicación Intranet, se deberá buscar una librería para generar tokens JWT que:
- Permita modificar y agregar campos del payload.
- Permita seleccionar el algoritmo para firmar o encriptar (HS256 por defecto).
- Sea del lado del servidor, que corra en el backend.
- No exponga la clave secreta.
El proceso para generar tokens, puede probarse fácilmente en https://jwt.io/
- Verificar que el header esté como sigue:
{ "alg": "HS256", "typ": "JWT" }
- Ingresar el payload como se describe en “Estructura del token JWT” - Ingresar la clave secreta de JWT_APP_SECRET en “Verify signature” Al finalizar, sobre el panel titulado “Encoded” estará el valor del token que se encuentra codificado en base64 por norma, el cual podrá utilizarse en nuestra instalación jitsi. Para ello se deberá ingresar a la conferencia establecida en el campo “room” del payload, agregando a la url el parámetro jwt, seguido del valor del token. El formato es el siguiente:
https://HOST_JITSI/VALOR_CAMPO_ROOM?jwt=VALOR_TOKEN
Si todo salió bien, se habrá ingresado a la conferencia como moderador y con datos como el nombre y el avatar (si se establecieron) cargados en la UI.