Partage via


Configurer un fournisseur de courrier personnalisé pour les événements d’envoi d’un code secret à usage unique (préversion)

S’applique à :Cercle blanc avec un symbole X gris. Locataires de main-d’œuvre Cercle vert avec un symbole de coche blanche. Locataires externes (en savoir plus)

Cet article fournit un guide sur la configuration et la configuration d’un fournisseur de messagerie personnalisé pour le type d’événement Envoyer un code secret à usage unique (OTP). L’événement est déclenché lorsqu’un e-mail OTP est activé, il vous permet d’appeler une API REST pour utiliser votre propre fournisseur de messagerie en appelant une API REST.

Conseil

Essayez-le dès maintenant

Pour essayer cette fonctionnalité, accédez à la démonstration Woodgrove Groceries et démarrez le cas d’usage« Utilisation d’un fournisseur de courrier personnalisé pour un code à usage unique ».

Prérequis

Étape 1 : créer une application de fonction Azure

Cette section vous montre comment configurer une application de fonction Azure dans le portail Azure. L’API de fonction est la passerelle vers votre fournisseur de messagerie. Vous créez une application de fonction Azure pour héberger la fonction de déclencheur HTTP et configurer les paramètres dans la fonction.

Conseil

Les étapes décrites dans cet article peuvent varier légèrement en fonction du portail de départ.

  1. Connectez-vous au Portail Microsoft Azure en tant qu’administrateur(-trice) d’application et administrateur(-trice) d’authentification.

  2. Dans le menu du portail Azure ou dans la page Accueil, sélectionnez Créer une ressource.

  3. Recherchez et sélectionnez Application de fonction, puis sélectionnez Créer.

  4. Dans la page Créer une application de fonction, sélectionnez Consommation, puis Sélectionner.

  5. Dans la page Créer une application de fonction (consommation), sous l’onglet Informations de base, créez une application de fonction à l’aide des paramètres spécifiés dans le tableau suivant :

    Setting Valeur suggérée Description
    Abonnement Votre abonnement Abonnement dans lequel est créée cette application de fonction.
    Groupe de ressources myResourceGroup Sélectionnez le groupe de ressources utilisé pour configurer les ressources Azure Communications Service et service de communication par e-mail dans le cadre des conditions préalables
    Nom de l’application de fonction Nom globalement unique Nom qui identifie la nouvelle application de fonction. Les caractères valides sont a-z (insensible à la casse), 0-9et -.
    Déployer du code ou une image conteneur Code Option permettant de publier des fichiers de code ou un conteneur Docker. Pour les besoins de ce didacticiel, sélectionnez Code.
    Pile d’exécution .NET Votre langage de programmation préféré. Pour les besoins de ce didacticiel, sélectionnez .NET.
    Version 8 (LTS) in-process Version du runtime .NET. In-process signifie que vous pouvez créer et modifier des fonctions dans le portail, ce qui est recommandé pour ce guide
    Région Région recommandée Sélectionnez une région proche de chez vous, ou proche d’autres services auxquels vos fonctions peuvent accéder.
    Système d’exploitation Windows Le système d’exploitation est présélectionné pour vous en fonction de la pile d’exécution que vous avez sélectionnée.
  6. Sélectionnez Vérifier + créer pour passer en revue les sélections de configuration d’application, puis sélectionnez Créer. Le déploiement prend quelques minutes.

  7. Une fois le déploiement effectué, sélectionnez Accéder à la ressource pour voir votre nouvelle application de fonction.

1.1 Créer une fonction de déclencheur HTTP

Une fois l’application de fonction Azure créée, créez une fonction de déclencheur HTTP. Le déclencheur HTTP vous permet d’appeler une fonction avec une requête HTTP. Ce déclencheur HTTP est référencé par votre extension d’authentification personnalisée Microsoft Entra.

  1. Dans votre application de fonction, dans le menu, sélectionnez Fonctions.
  2. Sélectionnez Créer une fonction.
  3. Dans la fenêtre Créer une fonction , sous Sélectionner un modèle, recherchez et sélectionnez le modèle de déclencheur HTTP. Cliquez sur Suivant.
  4. Sous Détails du modèle, entrez CustomAuthenticationExtensionsAPI pour la propriété nom de fonction.
  5. Pour le niveau d’autorisation, sélectionnez Fonction.
  6. Sélectionnez Créer.

1.2 Modifier la fonction

Le code commence par la lecture de l’objet JSON entrant. Microsoft Entra ID envoie l’objet JSON à votre API. Dans cet exemple, il lit l’adresse e-mail (identificateur) et l’OTP. Ensuite, le code envoie les détails au service de communication pour envoyer l’e-mail à l’aide d’un modèle dynamique.

Ce guide pratique montre l’événement d’envoi OTP à l’aide d’Azure Communication Services et SendGrid. Utilisez les onglets pour sélectionner votre implémentation.

  1. Dans le menu, sélectionnez Code + test.

  2. Remplacez l’intégralité du code par l’extrait de code suivant :

    using System.Dynamic;
    using System.Text.Json;
    using System.Text.Json.Nodes;
    using System.Text.Json.Serialization;
    using Azure.Communication.Email;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Http.HttpResults;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Azure.Functions.Worker;
    using Microsoft.Extensions.Logging;
    
    namespace Company.AuthEvents.OnOtpSend.CustomEmailACS
    {
        public class CustomEmailACS
        {
            private readonly ILogger<CustomEmailACS> _logger;
    
            public CustomEmailACS(ILogger<CustomEmailACS> logger)
            {
                _logger = logger;
            }
    
            [Function("OnOtpSend_CustomEmailACS")]
            public async Task<IActionResult> RunAsync([HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequest req)
            {
                _logger.LogInformation("C# HTTP trigger function processed a request.");
    
                // Get the request body
                string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
                JsonNode jsonPayload = JsonNode.Parse(requestBody)!;
    
                // Get OTP and mail to
                string emailTo = jsonPayload["data"]!["otpContext"]!["identifier"]!.ToString();
                string otp = jsonPayload["data"]!["otpContext"]!["onetimecode"]!.ToString();
    
                // Send email
                await SendEmailAsync(emailTo, otp);
    
                // Prepare response
                ResponseObject responseData = new ResponseObject("microsoft.graph.OnOtpSendResponseData");
                responseData.Data.Actions = new List<ResponseAction>() { new ResponseAction(
                    "microsoft.graph.OtpSend.continueWithDefaultBehavior") };
    
                return new OkObjectResult(responseData);
            }
    
            private async Task SendEmailAsync(string emailTo, string code)
            {
                // Get app settings
                var connectionString = Environment.GetEnvironmentVariable("mail_connectionString");
                var sender = Environment.GetEnvironmentVariable("mail_sender");
                var subject = Environment.GetEnvironmentVariable("mail_subject");
    
                try
                {
                    if (!string.IsNullOrEmpty(connectionString))
                    {
                        var emailClient = new EmailClient(connectionString);
                        var body = EmailTemplate.GenerateBody(code);
    
                        _logger.LogInformation($"Sending OTP to {emailTo}");
    
                        EmailSendOperation emailSendOperation = await emailClient.SendAsync(
                        Azure.WaitUntil.Started,
                        sender,
                        emailTo,
                        subject,
                        body);
                    }
                }
                catch (System.Exception ex)
                {
                    _logger.LogError(ex.Message);
                }
            }
        }
    
        public class ResponseObject
        {
            [JsonPropertyName("data")]
            public Data Data { get; set; }
    
            public ResponseObject(string dataType)
            {
                Data = new Data(dataType);
            }
        }
    
        public class Data
        {
            [JsonPropertyName("@odata.type")]
            public string DataType { get; set; }
            [JsonPropertyName("actions")]
            public List<ResponseAction> Actions { get; set; }
    
            public Data(string dataType)
            {
                DataType = dataType;
            }
        }
    
        public class ResponseAction
        {
            [JsonPropertyName("@odata.type")]
            public string DataType { get; set; }
    
            public ResponseAction(string dataType)
            {
                DataType = dataType;
            }
        }
    
        public class EmailTemplate
        {
            public static string GenerateBody(string oneTimeCode)
            {
                return @$"<html><body>
                <div style='background-color: #1F6402!important; padding: 15px'>
                    <table>
                    <tbody>
                        <tr>
                            <td colspan='2' style='padding: 0px;font-family: "Segoe UI Semibold", "Segoe UI Bold", "Segoe UI", "Helvetica Neue Medium", Arial, sans-serif;font-size: 17px;color: white;'>Woodgrove Groceries live demo</td>
                        </tr>
                        <tr>
                            <td colspan='2' style='padding: 15px 0px 0px;font-family: "Segoe UI Light", "Segoe UI", "Helvetica Neue Medium", Arial, sans-serif;font-size: 35px;color: white;'>Your Woodgrove verification code</td>
                        </tr>
                        <tr>
                            <td colspan='2' style='padding: 25px 0px 0px;font-family: "Segoe UI", Tahoma, Verdana, Arial, sans-serif;font-size: 14px;color: white;'> To access <span style='font-family: "Segoe UI Bold", "Segoe UI Semibold", "Segoe UI", "Helvetica Neue Medium", Arial, sans-serif; font-size: 14px; font-weight: bold; color: white;'>Woodgrove Groceries</span>'s app, please copy and enter the code below into the sign-up or sign-in page. This code is valid for 30 minutes. </td>
                        </tr>
                        <tr>
                            <td colspan='2' style='padding: 25px 0px 0px;font-family: "Segoe UI", Tahoma, Verdana, Arial, sans-serif;font-size: 14px;color: white;'>Your account verification code:</td>
                        </tr>
                        <tr>
                            <td style='padding: 0px;font-family: "Segoe UI Bold", "Segoe UI Semibold", "Segoe UI", "Helvetica Neue Medium", Arial, sans-serif;font-size: 25px;font-weight: bold;color: white;padding-top: 5px;'>
                            {oneTimeCode}</td>
                            <td rowspan='3' style='text-align: center;'>
                                <img src='https://woodgrovedemo.com/custom-email/shopping.png' style='border-radius: 50%; width: 100px'>
                            </td>
                        </tr>
                        <tr>
                            <td style='padding: 25px 0px 0px;font-family: "Segoe UI", Tahoma, Verdana, Arial, sans-serif;font-size: 14px;color: white;'> If you didn't request a code, you can ignore this email. </td>
                        </tr>
                        <tr>
                            <td style='padding: 25px 0px 0px;font-family: "Segoe UI", Tahoma, Verdana, Arial, sans-serif;font-size: 14px;color: white;'> Best regards, </td>
                        </tr>
                        <tr>
                            <td>
                                <img src='https://woodgrovedemo.com/Company-branding/headerlogo.png' height='20'>
                            </td>
                            <td style='font-family: "Segoe UI", Tahoma, Verdana, Arial, sans-serif;font-size: 14px;color: white; text-align: center;'>
                                <a href='https://woodgrovedemo.com/Privacy' style='color: white; text-decoration: none;'>Privacy Statement</a>
                            </td>
                        </tr>
                    </tbody>
                    </table>
                </div>
                </body></html>";
            }
        }
    }
    
  3. Sélectionnez Obtenir l’URL de fonction, puis copiez la clé de la fonction, qui est désormais utilisée et appelée {Function_Url}. Fermer la fonction.

Étape 2 : Ajouter des chaînes de connexion à la fonction Azure

Les chaînes de connexion permettent aux kits SDK Communication Services pour se connecter et s’authentifier auprès d’Azure. Pour Azure Communication Services et SendGrid, vous devez ensuite ajouter ces chaînes de connexion à votre application De fonction Azure en tant que variables d’environnement.

2.1 : Extraire les chaînes de connexion et les points de terminaison de service de votre ressource Azure Communication Services

Vous pouvez accéder à vos chaînes de connexion et points de terminaison de service Communication Services à partir du portail Azure, ou programmatiquement à l’aide des API Azure Resource Manager.

  1. À partir de la page Accueil du portail Azure, ouvrez le menu du portail, recherchez et sélectionnez Toutes les ressources.

  2. Recherchez et sélectionnez le Azure Communications Service créé dans le cadre des Conditions requises à cet article.

  3. Dans le volet gauche, sélectionnez la liste déroulante paramètres , puis sélectionnez Clés.

  4. Copiez le point de terminaisonet, à partir de clé primaire copiez les valeurs pour clé et chaîne de connexion.

    Capture d’écran de la page Clés du service Azure Communications montrant les emplacements de point de terminaison et de clé.

2.2 : Ajouter les chaînes de connexion à la fonction Azure

  1. Revenez à la fonction Azure que vous avez créée dans Créer une application de fonction Azure.

  2. Dans la page Vue d’ensemble de votre application de fonction, dans le menu de gauche, sélectionnez Paramètres>Variables d’environnement ajoutez les paramètres d’application suivants. Une fois tous les paramètres ajoutés, sélectionnez Appliquer, puis Confirmer.

    Setting Valeur (exemple) Description
    mail_connectionString A1bC2dE3fH4iJ5kL6mN7oP8qR9sT0u Clé primaire Azure Communication Services.
    mail_sender from.email@myemailprovider.com Adresse e-mail « À partir de »
    mail_subject Démonstration CIAM Objet de l’e-mail.

Étape 3 : inscrire une extension d’authentification personnalisée

Dans cette étape, vous allez configurer une extension d’authentification personnalisée, que Microsoft Entra ID utilise pour appeler votre fonction Azure. L’extension d’authentification personnalisée contient des informations sur votre point de terminaison d’API REST, les revendications qu’elle analyse à partir de votre API REST et la façon de s’authentifier auprès de votre API REST. Utilisez le portail Azure ou Microsoft Graph pour inscrire une application pour authentifier votre extension d’authentification personnalisée auprès de votre fonction Azure.

Inscrire une extension d’authentification personnalisée

  1. Connectez-vous au Portail Microsoft Azure en tant qu’administrateur(-trice) d’application et administrateur(-trice) d’authentification.

  2. Recherchez et sélectionnez Microsoft Entra ID, puis Applications d’entreprise.

  3. Sélectionnez Extensions d’authentification personnalisées, puis Créer une extension personnalisée.

  4. Dans De base, sélectionnez le type d’événement EmailOtpSend, puis sélectionnez suivant.

    Capture d’écran du portail Azure mettant en évidence l’événement d’envoi du mot de passe à usage unique par e-mail.

  5. Sous l’onglet configuration du point de terminaison, renseignez les propriétés suivantes, puis sélectionnez suivant pour continuer.

    • Nom : spécifiez un nom pour votre extension d’authentification personnalisée. Par exemple, envoi d’e-mail OTP.
    • URL cible : {Function_Url} de l’URL de votre fonction Azure. Accédez à la page Vue d’ensemble de votre application de fonction Azure, puis sélectionnez la fonction que vous avez créée. Dans la page Présentation de la fonction, sélectionnez Obtenir l’URL de la fonction et utilisez l’icône de copie pour copier l’URL customauthenticationextension_extension (clé système).
    • Description : description de vos extensions d’authentification personnalisées.
  6. Sous l’onglet authentification de l’API, sélectionnez l’option Créer une inscription d’application pour créer une inscription d’application qui représente votre application de fonction.

  7. Donnez un nom à l’application, par exemple API d’événements d’authentification Azure Functions, puis sélectionnez suivant.

  8. Sous l’onglet Applications, sélectionnez l’application à associer à l’extension d’authentification personnalisée. Cliquez sur Suivant. Vous avez la possibilité de l’appliquer sur l’ensemble du locataire en cochant la case. Sélectionnez Suivant pour continuer.

  9. Sous l’onglet Vérifier, vérifiez que les détails sont corrects pour l’extension d’authentification personnalisée. Notez l’ID d’application sous Authentification d’API, qui est nécessaire pour configurer l’authentification pour votre fonction Azure dans votre application de fonction Azure. Sélectionnez Créer.

Une fois votre extension d’authentification personnalisée créée, ouvrez l’application à partir du portail sous inscriptions d’applications et sélectionnez autorisations d’API.

Dans la page autorisations de l’API, sélectionnez le bouton Accorder le consentement de l’administrateur pour « YourTenant » pour donner son consentement administrateur à l’application inscrite, ce qui permet à l’extension d’authentification personnalisée de s’authentifier auprès de votre API. L’extension d’authentification personnalisée utilise client_credentials pour s’authentifier auprès de l’application de fonction Azure à l’aide de l’autorisation Receive custom authentication extension HTTP requests.

La capture d'écran suivante illustre comment accorder des autorisations :

Capture d’écran du portail Azure et comment accorder le consentement de l’administrateur.

Étape 4 : Configurer une application OpenID Connect à tester avec

Pour obtenir un jeton et tester l’extension d’authentification personnalisée, vous pouvez utiliser l’application https://jwt.ms. Il s’agit d’une application Web Microsoft qui affiche le contenu décodé d’un jeton (le contenu du jeton ne quitte jamais votre navigateur).

Procédez comme suit pour inscrire l’application web jwt.ms :

4.1 Inscrire une application web de test

  1. Connectez-vous au Centre d’administration Microsoft Entra au moins en tant qu’Administrateur d’application.
  2. Accédez à Identité>Applications>Inscriptions d’applications.
  3. Sélectionnez Nouvelle inscription.
  4. Entrez un Nom pour l’application. Par exemple, Mon application de test.
  5. Sous Types de comptes pris en charge, sélectionnez Comptes dans cet annuaire organisationnel uniquement.
  6. Dans la liste déroulante Sélectionner une plateforme dans URI de redirection, sélectionnez Web, puis entrez https://jwt.ms dans la zone de texte URL.
  7. Sélectionnez Inscrire pour procéder à l’inscription d’application.
  8. Dans l’inscription de votre application, sous Vue d’ensemble, copiez l’ID d’application (client), qui est utilisé ultérieurement et appelé {App_to_sendotp_ID}. Dans Microsoft Graph, il est référencé par la propriété appId.

La capture d’écran suivante montre comment inscrire Mon application de test.

Capture d’écran montrant comment sélectionner le type de compte et l’URI de redirection pris en charge.

4.1 Récupérer l’ID de l’application

Dans l’inscription de votre application, sous Vue d’ensemble, copiez l’ID d’application (client). L’ID d’application est appelé {App_to_sendotp_ID} dans les étapes ultérieures. Dans Microsoft Graph, il est référencé par la propriété appId.

4.2 Activer le flux implicite

L’application de test jwt.ms utilise le flux implicite. Activez le flux implicite dans l’inscription Mon application de test :

  1. Sous Gérer, sélectionnez Authentification.
  2. Sous Flux d’octroi implicite et flux hybride, cochez la case Jetons d’ID (utilisés pour les flux implicites et hybrides).
  3. Cliquez sur Enregistrer.

Remarque

L’application jwt.ms utilise le flux implicite pour obtenir un jeton d’ID et est à des fins de test uniquement. Le flux implicite n’est pas recommandé pour les applications de production. Pour les applications de production, utilisez le flux de code d’autorisation.

Étape 5 : Protéger votre fonction Azure

L’extension d’authentification personnalisée Microsoft Entra utilise le flux de serveur à serveur pour obtenir un jeton d’accès envoyé dans l’en-tête HTTP Authorization à votre fonction Azure. Lorsque vous publiez votre fonction sur Azure, en particulier dans un environnement de production, vous devez valider le jeton envoyé dans l’en-tête d’autorisation.

Pour protéger votre fonction Azure, suivez ces étapes pour intégrer l’authentification Microsoft Entra, afin de valider les jetons entrants avec votre inscription d’application API d’événements d’authentification Azure Functions.

Remarque

Si l’application de fonction Azure est hébergée dans un locataire Azure différent du locataire dans lequel votre extension d’authentification personnalisée est inscrite, passez à l’étape utiliser le fournisseur d’identité OpenID Connect.

  1. Connectez-vous au portail Azure.
  2. Accédez à et sélectionnez l’application de fonction que vous avez publiée précédemment.
  3. Sélectionnez Authentification dans le menu de gauche.
  4. Sélectionnez Ajouter un fournisseur d’identité.
  5. Dans le menu déroulant et sélectionnez Microsoft en tant que fournisseur d’identité.
  6. Sous inscription d’application :>type d’inscription d’application, sélectionnez Choisissez une inscription d’application existante dans ce répertoire et choisissez l’inscription d’applicationAPI d’événements d’authentification Azure Functions que vous précédemment créée lors de l’inscription du fournisseur de messagerie personnalisé.
  7. Ajoutez l’expiration clé secrète client de l’application.
  8. Sous Requêtes non authentifiées, sélectionnez HTTP 401 Non autorisé comme fournisseur d’identité.
  9. Désélectionnez l’option Magasin de jetons.
  10. Sélectionnez Ajouter pour ajouter l’authentification à votre fonction Azure.

Capture d’écran montrant comment ajouter une authentification à votre application de fonction.

5.1 Utiliser un fournisseur d’identité OpenID Connect

Si vous avez configuré le fournisseur d’identité Microsoft, ignorez cette étape. Sinon, si la fonction Azure est hébergée sous un locataire différent du locataire dans lequel votre extension d’authentification personnalisée est inscrite, procédez comme suit pour protéger votre fonction :

  1. Connectez-vous au Portail Azure, ensuite accédez et sélectionnez l’application de fonction que vous avez publiée précédemment.

  2. Sélectionnez authentification dans le volet gauche.

  3. Sélectionnez Ajouter un fournisseur d’identité.

  4. Sélectionnez OpenID Connect en tant que fournisseur d'identité.

  5. Fournissez un nom, tel que Contoso Microsoft Entra ID.

  6. Sous l’entrée Métadonnées, entrez l’URL suivante pour l’URL du document. Remplacez le {tenantId} par votre ID de locataire Microsoft Entra et {tenantname} par le nom de votre locataire sans le « onmicrosoft.com ».

    https://{tenantname}.ciamlogin.com/{tenantId}/v2.0/.well-known/openid-configuration
    
  7. Sous Inscription de l’application, entrez l’ID d’application (ID client) de l’inscription de l’application API des événements d’authentificationd’Azure Functions que vous avez créée précédemment.

  8. Dans le centre d’administration Microsoft Entra :

    1. Sélectionnez l’inscription d’applicationAPI des événements d’authentification Azure Functions que vous avez créée précédemment.
    2. Sélectionnez Certificats et secrets>Clés secrètes client>Nouvelle clé secrète client.
    3. Ajoutez une description pour votre clé secrète client.
    4. Sélectionnez un délai d’expiration pour le secret ou spécifiez une durée de vie personnalisée.
    5. Sélectionnez Ajouter.
    6. Enregistrez la valeur du secret en prévision d’une utilisation dans le code de votre application cliente. Cette valeur secrète ne sera plus jamais affichée lorsque vous aurez quitté cette page.
  9. De retour à la fonction Azure, sous l’inscription de l’application, entrez le secret du client.

  10. Désélectionnez l’option Magasin de jetons.

  11. Sélectionnez Ajouter pour ajouter le fournisseur d’identité OpenID Connect.

Étape 6 : Tester l’application

Pour tester votre fournisseur de messagerie personnalisé, procédez comme suit :

  1. Ouvrez un nouveau navigateur privé et naviguez et connectez-vous à l’URL suivante.

    https://{tenantname}.ciamlogin.com/{tenant-id}/oauth2/v2.0/authorize?client_id={App_to_sendotp_ID}&response_type=id_token&redirect_uri=https://jwt.ms&scope=openid&state=12345&nonce=12345
    
  2. Remplacez {tenant-id} votre ID de locataire, votre nom de locataire ou l’un de vos noms de domaine vérifiés. Par exemple : contoso.onmicrosoft.com.

  3. Remplacez {tenantname} par le nom de votre locataire sans « onmicrosoft.com ».

  4. Remplacez {App_to_sendotp_ID} par l’ID d’inscription de Mon application de test.

  5. Vérifiez que vous vous connectez à l’aide d’un compte de code secret à usage unique e-mail. Sélectionnez ensuite envoi de code. Vérifiez que le code envoyé aux adresses e-mail inscrites utilise le fournisseur personnalisé inscrit ci-dessus.

Étape 7 : Revenir au fournisseur Microsoft

Si une erreur se produit dans votre API d’extension, par défaut, Entra ID n’envoie pas d’OTP à l’utilisateur. Vous pouvez à la place définir le comportement en cas d’erreur pour revenir au fournisseur Microsoft.

Pour l’activer, exécutez la requête suivante. Remplacez {customListenerOjectId} par l’ID d’écouteur d’authentification personnalisé enregistré précédemment.

  • Vous avez besoin de la permission déléguée EventListener.ReadWrite.All.
PATCH https://graph.microsoft.com/beta/identity/authenticationEventListeners/{customListenerOjectId}

{
    "@odata.type": "#microsoft.graph.onEmailOtpSendListener",
    "handler": {
        "@odata.type": "#microsoft.graph.onOtpSendCustomExtensionHandler",
        "configuration": {
            "behaviorOnError": {
                "@odata.type": "#microsoft.graph.fallbackToMicrosoftProviderOnError"
            }
        }
    }
}

Voir aussi