Este módulo permite a Anjana Data conectarse a su inquilino de Microsoft Azure (Entra ID) para descargar y sincronizar usuarios.
Existen dos modos de sincronización según si se configura o no el service-principal-id:
-
Modo filtrado por Aplicación Empresarial (con
service-principal-id): Anjana consulta la API de Microsoft Graph para obtener únicamente los usuarios y grupos asignados a esa aplicación en Azure. Recomendado cuando solo un subconjunto de usuarios del tenant debe tener acceso. -
Modo tenant completo (sin
service-principal-id): Anjana sincroniza todos los usuarios del tenant de Azure AD. Útil cuando todos los usuarios del directorio deben tener acceso.
Parte 1: Configuración en Azure Portal
Para configurar la provisión, necesitamos un Registro de Aplicación (para credenciales de API) y, opcionalmente, una Aplicación Empresarial (si se desea filtrar usuarios por aplicación).
Paso 1: Crear el Registro de Aplicación (API Credentials)
-
Vaya a Microsoft Entra ID > Registros de aplicaciones (App registrations).
-
Haga clic en Nuevo registro.
-
Asígnele un nombre (ej.
Anjana Data Provisioning) y haga clic en Registrar. -
Obtener Credenciales:
-
En "Información general", copie el Id. de directorio (inquilino) (
tenant-id). -
Copie el Id. de aplicación (cliente) (
client-id).
-
-
Crear Secreto:
-
Vaya a Certificados y secretos > Nuevo secreto de cliente.
-
Añada una descripción y una expiración.
-
Copie el Valor del secreto (¡Importante! Copie el valor, no el ID). Este será su
client-secret.
-
Paso 2: Asignar Permisos de API
Para que Anjana pueda leer los usuarios, el registro creado necesita permisos sobre Microsoft Graph.
-
En el menú del Registro de Aplicación, vaya a Permisos de API.
-
Haga clic en + Agregar un permiso > Microsoft Graph > Permisos de aplicación (NO permisos delegados).
-
Busque y marque los siguientes permisos:
-
User.Read.All(Para leer perfiles de usuario). -
GroupMember.Read.All(Para leer miembros de grupos si usa asignación por grupos). -
Application.Read.All(Para leer la configuración de la aplicación). -
AppRoleAssignment.ReadWrite.All(Para leer quién está asignado a la app; solo necesario en modo filtrado por aplicación).
-
-
Haga clic en Agregar permisos.
-
CRUCIAL: Haga clic en "Conceder consentimiento de administrador para..." y confirme con "Sí". Los permisos deben mostrar un tick verde en la columna de estado.
Paso 3: Obtener el Service Principal ID (Opcional — solo para modo filtrado por aplicación)
Este paso solo es necesario si desea restringir la sincronización a los usuarios asignados a una Aplicación Empresarial concreta. Si omite service-principal-id, Anjana sincronizará todos los usuarios del tenant.
-
Vaya al menú principal de Microsoft Entra ID > Aplicaciones empresariales (Enterprise Applications).
-
Busque la aplicación creada en el Paso 1 (puede buscar por nombre o por el Client ID).
-
Haga clic en la aplicación para abrirla.
-
Vaya a Propiedades en el menú lateral.
-
Copie el Id. de objeto. Este valor es el
service-principal-id.-
Nota: Asegúrese de que este ID sea diferente del "Id. de aplicación (cliente)".
-
Parte 2: Configuración en application.yml
Edite el archivo de configuración de Anjana e incluya los datos obtenidos en la sección security.provisioning.providers.azure-graph.
Modo filtrado por Aplicación Empresarial (con service-principal-id)
Solo se sincronizan los usuarios asignados a la aplicación indicada (directamente o a través de grupos).
security:
provisioning:
providers:
azure-graph:
azure-prod:
tenant-id: "88888888-4444-4444-4444-121212121212"
client-id: "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
client-secret: "XyZ123..."
# Id. de objeto de la APLICACIÓN EMPRESARIAL (Paso 3)
service-principal-id: "99999999-5555-5555-5555-333333333333"
Modo tenant completo (sin service-principal-id)
Se sincronizan todos los usuarios del tenant de Azure AD.
security:
provisioning:
providers:
azure-graph:
azure-prod:
tenant-id: "88888888-4444-4444-4444-121212121212"
client-id: "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
client-secret: "XyZ123..."
# service-principal-id no configurado → sincronización de todo el tenant
Resumen de Datos Requeridos
|
Propiedad YAML |
Nombre en Azure Portal |
Dónde encontrarlo |
Obligatorio |
|---|---|---|---|
|
|
Id. de directorio (inquilino) |
App Registration > Información general |
Sí |
|
|
Id. de aplicación (cliente) |
App Registration > Información general |
Sí |
|
|
Valor del secreto |
App Registration > Certificados y secretos |
Sí |
|
|
Id. de objeto |
Aplicaciones empresariales > Propiedades |
No (opcional) |
Cuando service-principal-id está ausente o vacío, Anjana usa la API GET /users de Microsoft Graph con paginación OData para obtener todos los usuarios del tenant. Cuando está presente, usa GET /servicePrincipals/{id}/appRoleAssignedTo para obtener solo los usuarios y grupos asignados a esa aplicación, expandiendo los grupos de forma transitiva.
Mapeo de campos personalizado (field-mapping)
Anjana incluye un mapeo por defecto que cubre los casos habituales. Puede sobreescribir cualquier campo indicando la clave del proveedor de la que debe leer el valor. Las claves son listas en orden de prioridad: se usa el primer valor no vacío.
Mapeo por defecto
|
Campo Anjana |
Claves por defecto (orden de prioridad) |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Campos disponibles
|
Clave |
Descripción |
|---|---|
|
|
Identificador único del objeto en Azure AD. |
|
|
UPN del usuario (ej. |
|
|
Nombre para mostrar. |
|
|
Correo electrónico principal. |
|
|
Lista de correos adicionales. |
|
|
Nombre de pila. |
|
|
Apellidos. |
|
|
Teléfono móvil. |
|
|
Lista de teléfonos de empresa. |
|
|
Cargo. |
|
|
Departamento. |
|
|
Ubicación de la oficina. |
|
|
Nombre de la empresa. |
|
|
Identificador de empleado. |
|
|
Idioma preferido (ej. |
Ejemplo de configuración
security:
provisioning:
providers:
azure-graph:
azure-prod:
tenant-id: "..."
client-id: "..."
client-secret: "..."
field-mapping:
# Usar mail en lugar de userPrincipalName como login
user-name: ["mail"]
# Teléfono de empresa con fallback a móvil
phone: ["businessPhones", "mobilePhone"]
# Cargo; si está vacío, usar el departamento
title: ["jobTitle", "department"]