top of page
  • Foto del escritorAndres Biarge

Sincronizar usuarios entre AAD y Dataverse (2) - Añadir nuevos miembros automáticamente

Estaba hablando con mi amigo Sumit Rai, y me preguntó por cómo podíamos aplicar lo aprendido con mi anterior artículo sobre este tema (Sincronizar usuarios entre AAD y Dataverse (andresbiarge.com)) para sincronizar los usuarios de Azure AD / Microsoft Entra ID de forma "automáticamente proactiva" con un entorno Dataverse en PROD.


Nota:



Note: en el artículo, vimos cómo podemos sincronizar usuarios en masa. Justo antes del Go Live de una aplicación con muchos usuarios. Pero cuando tu aplicación lleve ya un tiempo en funcionamiento, tendrás usuarios que necesitarán ser sincronizados automáticamente para superar cualquier obstáculo de adopción.


Así, acordamos estudiar el asunto por separado y reunirnos cuando hubiéramos llegado a alguna solución. Ambos propusimos dos enfoques diferentes:

  1. Utilizar Microsoft Graph Webhooks para recibir notificaciones cada vez que se asigna un usuario al grupo de seguridad.

  2. Utilizar Microsoft Graph Delta Queries para preguntar por los últimos cambios con una aproximación tipo polling.

La diferencia entre los dos enfoques es la de una arquitectura Polling vs Event-driven.

En este artículo, te mostraré lo que he aprendido probando ambos enfoques.



Venga, basta de cháchara 💪.



Vídeo de acompañamiento en YouTube

He creado este vídeo para que tengas un paso a paso más guiado y donde te muestro cómo testearlo. Échale un vistazo aquí:




Método #1 Usando Microsoft Graph Webhooks

Con este diseño, necesitarás crear un Listener / Webhook para recibir cualquier cambio en el Grupo de Seguridad que protege tu entorno Power Platform. La forma más rápida, barata y sencilla de hacerlo es a través de una Azure Function. Para este ejemplo, decidí que no quería invertir mucho en la seguridad de la Azure Function (certificados/client-secrets/etc.), por lo que la sincronización entre Azure Entra ID y Dataverse se realiza a través de un Power Automate cloud flow.

Solution Architecture Diagram
Solution Architecture Diagram

Documentación que necesitarás

Para comprender mejor este enfoque, te recomiendo que leas los siguientes artículos:

  1. Guía general sobre Webhooks y cuáles son los recursos de Graph que admiten Webhooks: Set up notifications for changes in resource data. - Microsoft Graph | Microsoft Learn

  2. Consideraciones de diseño al implementar Webhooks ("throttling", "handshake" de la suscripción, etc.): Receive change notifications through webhooks - Microsoft Graph | Microsoft Learn

  3. PowerShell Webhook Graph Library: Microsoft.Graph.ChangeNotifications Module | Microsoft Learn

Requisitos previos

Antes de explicar cómo configurar todos los recursos, necesitarás:

  1. Power Platform:

    1. Environment al que le puedas prender fuego sin que nadie se queje.

    2. Securizar el environment con un Security Group.

    3. System Administrator security role para tu usuario.

    4. Poder crear Power Automate cloud flows.

  2. Azure:

    1. Un Security Group del que seas dueño (owner).

    2. Una Azure Function App que puedas reventar sin problemas.

Orden de los pasos

Para que te resulte más fácil reproducir este caso, te recomiendo que sigas este orden:


1. Crear el Power Automate Flow.

2. Crea tu Azure Function (recomendación para rendimiento/consumo: PowerShell sobre Linux).

3. Registrar el Webhook en Microsoft Graph.


Configuración del Webhook


Import-Module Microsoft.Graph.ChangeNotifications

Connect-MgGraph -Scopes "User.Read.All","Group.Read.All"
$params = @{
  changeType = "updated"
  notificationUrl = "The URL of your Az. Function"
  resource = "/groups/{your-group-guid}/members"
  expirationDateTime = [System.DateTime]::Parse("<up to 29 days>")
  clientState = "<your secret for the Graph subscription>"
}

$newGraphSubscription = New-MgSubscription -BodyParameter $params

$newGraphSubscription
Disconnect-MgGraph

Recibirás una respuesta parecida a la siguiente:

$newGraphSubscription | ConvertTo-Json

Creación de la función Az. Function

Normalmente, mi lenguaje preferido para estas tareas es PowerShell. Es genial y un no brainer para configurarlo en cualquier entorno + se ejecuta en cualquier máquina.

Aquí tienes un snippet / plantilla que puedes usar para probar el Webhook:


using namespace System.Net

param($Request, $TriggerMetadata)

#First, we detect if this is the validation request
if ($Request.Query.validationToken) {
  $responseBody = [uri]::UnescapeDataString($Request.Query.validationToken)
  Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = [HttpStatusCode]::OK
    ContentType = "text/plain"
    Body = $responseBody
  })  
}else {
  #else,means we got the actual message
  foreach ($groupChange in $Request.Body.value) {
    if (-not $groupChange.resourceData."members@delta"."@removed") {
      #only call Flow when it's a new user.
      $webRequestParams = @{
        Uri = "<the URL of your HTTP triggered Power Automate Flow>"
        Method = "Post"
        ContentType = "application/json"
        Body = [PSCustomObject]@{
          clientState = "$($groupChange.clientState)";
          newUserId = "$($groupChange.resourceData."members@delta".id)";
        } | ConvertTo-Json
      }
      Invoke-WebRequest @webRequestParams
    }
  }
  
  Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = [HttpStatusCode]::OK
    ContentType = "text/plain"
    Body = "Ok"
  }) 
}

⚠¡Ojo!⚠: Cuidado con el ciclo de vida de los Webhooks

Los webhooks configurados para recibir notificaciones del segmento /groups sólo viven durante 29 días como máximo. Puedes comprobar este límite directamente desde la documentación aquí: subscription resource type - Microsoft Graph v1.0 | Microsoft Learn


Esto significa que tendrá que establecer un proceso para renovar la suscripción: Receive change notifications through webhooks - Microsoft Graph | Microsoft Learn


Son 5 líneas con PowerShell:


Import-Module Microsoft.Graph.ChangeNotifications

$params = @{
	expirationDateTime = [System.DateTime]::Parse("<your next renewal datetime>")
}

Update-MgSubscription -SubscriptionId $subscriptionId -BodyParameter $params 




Approach #2 Usando Microsoft Graph Delta Queries

Con este patrón, estarás preguntando a Microsoft Graph por cambios en el segmento /groups del Graph API con un patrón tipo polling. Bravo aquí, Microsoft, porque la forma en que está diseñado es muy práctico:


  1. Primero, tendrás que realizar una primera petición al endpoint /delta Graph API en el segmento /groups. Tendrás que utilizar un filtro OData para obtener la información del grupo o grupos que te interesen.

  2. Graph responderá con los cambios (miembros añadidos o eliminados). Debido a las capacidades de paginación de Graph, tendrás que implementar una lógica de "follow through": cada vez que veas un "@odata.nextLink", utiliza ese valor para realizar la siguiente petición de forma recursiva.

  3. Cuando veas que la respuesta de Graph ya no incluye un "@odata.nextLink", verás un "@odata.deltaLink". Guarda este valor en un almacenamiento persistente (por ejemplo, una tabla Dataverse). Este enlace es el que tendrás que utilizar la próxima vez que quieras obtener los cambios en el grupo o grupos de seguridad. Este "@odata.deltaLink" almacena el estado actual en el que lo dejaste, por lo que continuar desde ahí te asegurará obtener los últimos cambios reales en el recurso.

Una posible solución aquí es que configures un Power Automate cloud flow recurrente que realice esta lógica de sondeo con el "@odata.deltaLink" cada día a las 5 AM.

Puedes ver la implementación en vivo en mi vídeo complementario de YouTube.


Consideraciones a nivel Enterprise

Estas dos soluciones son perfectas para un único entorno en PROD. Pero, ¿qué pasa cuando queremos crear una solución más escalable que funcione para empresas con varias grandes soluciones que ya están en PROD?


Mi amigo Sumit y yo estuvimos discutiendo posibles soluciones para eso y llegamos a la conclusión de que usar un Azure Event Hub sería una muy buena solución. Por supuesto, este un enfoque recomendado por Microsoft: Receive change notifications through Azure Event Hubs - Microsoft Graph | Microsoft Learn.


Conclusión

Espero que el planteamiento del problema y la solución te hayan resultado útiles. He intentado explicar cómo abordar la sincronización automática y proactiva entre los nuevos miembros de un grupo de seguridad Azure Entra ID (el viejo Azure Active Directory) en un entorno Dataverse.


Por favor, escribe tus comentarios, preguntas y peticiones de nuevo contenido en la sección de comentarios que encontrarás más abajo. Asegúrate también de ver el vídeo complementario de YouTube y el resto del contenido que estoy intentando recopilar para ti tanto en mi blog como en mi canal de YouTube.


¡Nos vemos! 💪


Andrés

28 visualizaciones0 comentarios
bottom of page