← Volver al blog

20 de septiembre de 2026 · 3 min de lectura

OIDC en Fineract: dejar de administrar contraseñas en el core

Cómo delegar la autenticación de Apache Fineract a un proveedor de identidad (Keycloak, Entra ID, Google) con OpenID Connect, qué cambia en la API y qué no cambia en los permisos.

Seguridad · OIDC · Keycloak

Fineract trae dos modos de autenticación: Basic (usuario y contraseña propios, almacenados en m_appuser) y OAuth2, donde el core valida un token emitido por un proveedor de identidad externo. El primero es cómodo para una demo. El segundo es el único defendible para una institución vigilada: MFA, políticas de contraseña, bloqueo, auditoría de sesiones y baja de usuarios viven en el proveedor de identidad, no en una tabla del core.

Qué hace Fineract en modo OAuth2

Con FINERACT_SECURITY_OAUTH_ENABLED=true y FINERACT_SECURITY_BASICAUTH_ENABLED=false, Fineract deja de aceptar el header Authorization: Basic y se comporta como resource server: cada llamada a la API debe traer Authorization: Bearer <JWT>, y el JWT se valida contra el emisor configurado (SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI). Fineract descarga el JWKS del emisor, verifica la firma, la expiración y el issuer, y a partir del claim de usuario resuelve el AppUser.

Dos cosas que conviene tener claras antes de encender el interruptor:

  1. La autorización sigue siendo de Fineract. Los roles y permisos (m_role, m_permission) se siguen asignando en el core. OIDC responde quién es; Fineract responde qué puede hacer. Sincronizar grupos del IdP con roles de Fineract es un proyecto aparte, y en la mayoría de las instituciones no vale la pena: el catálogo de permisos del core es demasiado fino para mapearlo a grupos de directorio.
  2. El usuario debe existir en m_appuser con el mismo username que trae el token. Si el claim de usuario es el correo y los usuarios del core se crearon con un login corto, nadie entra. Se decide una convención antes de migrar, no después.

Configuración mínima con Keycloak

En Keycloak: un realm para la institución, un client confidencial para el front (Mifos Web App o el portal propio) y, si hay integraciones máquina a máquina, un client con client credentials por sistema. El audience del token debe incluir el identificador que Fineract espera; sin eso la validación falla con un 401 sin más explicación.

Variables de entorno relevantes en Fineract:

FINERACT_SECURITY_BASICAUTH_ENABLED=false
FINERACT_SECURITY_OAUTH_ENABLED=true
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI=https://idp.ejemplo.com/realms/banco

El emisor debe ser accesible desde el contenedor de Fineract (no solo desde el navegador del usuario). En despliegues con red privada este es el error número uno: el JWKS no se descarga y todo token es inválido.

Lo que cambia para las integraciones

Los sistemas que hoy llaman a Fineract con un usuario técnico y contraseña tienen que pasar a client credentials: piden un token al IdP con su client_id y client_secret, lo cachean hasta antes de expirar y lo renuevan. Es un cambio pequeño de código y un cambio grande de postura: el secreto rota en el IdP, el acceso se revoca en un clic y cada sistema queda identificado en la auditoría.

Para los jobs internos de Fineract (COB, acumulación de intereses) no cambia nada: corren dentro del proceso y no pasan por la API.

Orden recomendado de migración

  1. Encender OAuth2 en un ambiente de pruebas con Basic todavía activo, y validar el login de la web app.
  2. Crear en el IdP los usuarios con el username exacto de m_appuser; cargar MFA.
  3. Migrar integraciones a client credentials una por una.
  4. Apagar Basic en producción en una ventana con reversa preparada: el rollback es una variable de entorno.

Lo que no se debe hacer: mantener Basic “por si acaso” después de la salida. Mientras exista, es la puerta que nadie vigila.