Utiliser l’authentification OAuth avec Microsoft Dataverse

OAuth 2.0 est le protocole standard d’autorisation. Une fois que les utilisateurs d’application fournissent les informations d’identification pour l’authentification, OAuth détermine s’ils sont autorisés à accéder aux ressources.

Les applications clientes doivent prendre en charge l’utilisation d’OAuth pour accéder aux données à l’aide de l’API Web. OAuth active l’authentification à deux facteurs (2FA) ou l’authentification basée sur un certificat pour des scénarios d’application serveur à serveur.

OAuth exige un fournisseur d’entités pour l’authentification. Pour Dataverse, le fournisseur d’identité est Microsoft Entra ID. Pour vous authentifier à l’aide d’un compte d’entreprise ou d’établissement d’enseignement Microsoft, utilisez la bibliothèque d’authentification Microsoft (MSAL).

Notes

Cette rubrique présente les concepts courants relatifs à la connexion à Dataverse à l’aide d’OAuth avec les bibliothèques d’authentification. Ce contenu est axé sur la façon dont un développeur peut se connecter à Dataverse et non sur l’utilisation en interne d’OAuth ou des bibliothèques. Pour des informations complètes relatives à l’authentification, consultez la documentation Microsoft Entra ID. La rubrique Qu’est-ce que l’authentification ? est un bon début.

Les exemples que nous proposons sont pré-configurés avec des valeurs d’enregistrement appropriées de telle sorte que vous les exécutiez sans générer l’enregistrement de votre propre application. Lorsque vous publiez vos propres applications, vous devez utiliser vos propres valeurs d’enregistrement.

Enregistrement de l’application

Lorsque vous vous connectez avec OAuth, vous devez tout d’abord enregistrer une application dans votre client Microsoft Entra ID. La manière dont vous devez enregistrer votre application dépend du type d’application que vous souhaitez créer.

Dans tous les cas, commencez par les étapes de base pour enregistrer une application décrite dans l’article : Démarrage rapide : Enregistrer une application avec la plateforme d’identités Microsoft. Pour obtenir des instructions spécifiques sur Dataverse, consultez Procédure pas à pas : Enregistrer une application avec Microsoft Entra ID > Créer un enregistrement d’application.

Les décisions que vous devez prendre à cette étape dépendent notamment du choix du type d’application (voir ci-dessous).

Types d’enregistrement d’application

Lorsque vous enregistrez une application avec Microsoft Entra ID, vous devez choisir le type d’application. Vous pouvez enregistrer deux types d’applications :

Type d’application Description
Application Web/API Client Web
Type d’application cliente qui exécute tout le code sur un serveur Web.

Client basé sur un agent utilisateur
Type d’application cliente qui télécharge le code depuis un serveur Web et s’exécute dans un agent utilisateur (par exemple, un navigateur Web), comme une application sur une seule page.
natif Type d’application cliente installé de manière native sur un appareil.

Lorsque vous sélectionnez Application Web/APII, vous devez fournir une URL de connexion qui correspond à l’URL à laquelle Microsoft Entra envoie la réponse d’authentification, y compris un jeton si l’authentification a réussi. Lorsque vous développez une application, cette URL est généralement définie sur https://localhost/appname:[port] afin que vous puissiez développer et déboguer votre application localement. Lorsque vous publiez votre application, vous devez changer cette valeur avec l’URL publiée de l’application.

Lorsque vous sélectionnez Natif, vous devez fournir une URI de redirection. Cette URL est un identifiant unique vers lequel Microsoft Entra ID redirige l’agent utilisateur dans une demande OAuth 2.0. Cette URL est généralement une valeur au format suivant : app://<guid>.

Accorder l’accès à Dataverse

Si votre application est un client qui autorise l’utilisateur authentifié à exécuter des opérations, vous devez configurer l’application pour avoir l’autorisation déléguée Accéder à Dynamics 365 en tant qu’utilisateurs de l’organisation.

Pour connaître les étapes spécifiques pour définir les autorisations, consultez Procédure pas à pas : Enregistrer une application avec Microsoft Entra ID > Appliquer les autorisations.

Si votre application utilise l’authentification S2S (serveur à serveur), cette étape peut être ignorée. Cette configuration exige un utilisateur système spécifique et les opérations sont effectuées par ce compte d’utilisateur plutôt que par tout utilisateur qui doit être authentifié.

Utiliser les certificats et les clés secrètes client

Pour les scénarios serveur à serveur, il n’y a pas de compte d’utilisateur interactif à authentifier. Dans ces cas, vous devez fournir quelques moyens pour confirmer que l’application est fiable. Cela se fait via les certificats et les clés secrètes client.

Pour les applications enregistrées avec le type d’application Application Web/API, vous pouvez configurer les clés secrètes. Celles-ci sont définies à l’aide de la zone Clés sous Accès API dans Paramètres pour l’enregistrement de l’application.

Pour un type d’application ou l’autre, vous pouvez télécharger un certificat.

Pour plus d’informations : Se connecter en tant qu’application

Utiliser les bibliothèques d’authentification pour établir une connexion

Utilisez l’une des bibliothèques clientes d’authentification de Microsoft Entra ID prises en charge par Microsoft pour vous connecter à Dataverse , telles que la bibliothèque d’authentification Microsoft (MSAL). Cette bibliothèque est disponible pour différentes plateformes, comme décrit dans les liens fournis.

Notes

La bibliothèque d’authentification Azure Active Directory (ADAL) ne reçoit plus de mises à jour et ne sera prise en charge que jusqu’en juin 2022. MSAL est la bibliothèque d’authentification recommandée à utiliser pour les projets.

Pour un exemple de code qui illustre l’utilisation des bibliothèques MSAL pour l’authentification avec Dataverse voir Exemple de démarrage rapide.

Bibliothèques clientes .NET

Dataverse prend en charge l’authentification des applications avec le point de terminaison d’API Web à l’aide du protocole OAuth 2.0. Pour vos applications .NET personnalisées, utilisez MSAL pour l’authentification des applications avec le point de terminaison d’API Web.

Kit de développement logiciel (SDK) Dataverse pour .NET inclut des classes client CrmServiceClient et ServiceClient pour gérer l’authentification. La classe CrmServiceClient utilise actuellement ADAL pour l’authentification tandis que ServiceClient utilise MSAL. L’écriture de votre code d’application pour utiliser ces clients élimine le besoin de gérer directement l’authentification. Les deux clients fonctionnent avec les points de terminaison SDK et API Web.

Utiliser le jeton AccessToken avec vos requêtes

L’intérêt d’utiliser les bibliothèques d’authentification est d’obtenir un jeton d’accès que vous pouvez inclure dans vos requêtes. L’obtention du jeton ne nécessite que quelques lignes de code, et quelques lignes supplémentaires pour configurer un client HttpClient pour exécuter une requête.

Important

Comme démontré dans l’exemple de code de cet article, utilisez une portée « <environment-url> /user_impersonation » pour un client public. Pour un client confidentiel, utilisez une portée « <environment-url>/.défaut ».

Exemple simple

Ci-après figure la quantité minimale de code nécessaire pour exécuter une seule requête API Web, mais cette approche n’est pas recommandée. Notez que ce code utilise la bibliothèque MSAL et est tiré de l’exemple Démarrage rapide mentionné ci-dessus.

string resource = "https://contoso.api.crm.dynamics.com";
var clientId = "51f81489-12ee-4a9e-aaae-a2591f45987d";
var redirectUri = "http://localhost"; // Loopback for the interactive login.

// MSAL authentication
var authBuilder = PublicClientApplicationBuilder.Create(clientId)
    .WithAuthority(AadAuthorityAudience.AzureAdMultipleOrgs)
    .WithRedirectUri(redirectUri)
    .Build();
var scope = resource + "/user_impersonation";
string[] scopes = { scope };

AuthenticationResult token =
    authBuilder.AcquireTokenInteractive(scopes).ExecuteAsync().Result;

// Set up the HTTP client
var client = new HttpClient
{
    BaseAddress = new Uri(resource + "/api/data/v9.2/"),
    Timeout = new TimeSpan(0, 2, 0)  // Standard two minute timeout.
};

HttpRequestHeaders headers = client.DefaultRequestHeaders;
headers.Authorization = new AuthenticationHeaderValue("Bearer", token.AccessToken);
headers.Add("OData-MaxVersion", "4.0");
headers.Add("OData-Version", "4.0");
headers.Accept.Add(
    new MediaTypeWithQualityHeaderValue("application/json"));

// Web API call
var response = client.GetAsync("WhoAmI").Result;

cette approche simple ne représente pas un bon schéma à suivre, car le token expire sous une heure environ. Les bibliothèques MSAL masquent le jeton pour vous et l’actualisent à chaque appel de la méthode AcquireTokenInteractive. Cependant dans cet exemple simple, le jeton n’est acquis qu’une seule fois.

Exemple illustrant un gestionnaire de message DelegatingHandler

L’approche recommandée consiste à mettre en place une classe dérivée de DelegatingHandler et qui sera transmise au constructeur du HttpClient. Ce gestionnaire vous permet de remplacer la méthode HttpClient.SendAsync afin que le jeton d’accès soit actualisé par les appels de méthode AcquireToken* avec chaque requête envoyée par le client HTTP.

Vous trouverez, ci-après, un exemple d’une classe personnalisée dérivée du DelegatingHandler. Ce code est obtenu de l’exemple Démarrage rapide amélioré utilisant une bibliothèque d’authentification MSAL.

class OAuthMessageHandler : DelegatingHandler
{
    private AuthenticationHeaderValue authHeader;
    public OAuthMessageHandler(string serviceUrl, string clientId, string redirectUrl, string username, string password,
            HttpMessageHandler innerHandler)
        : base(innerHandler)
    {
        string apiVersion = "9.2";
        string webApiUrl = $"{serviceUrl}/api/data/v{apiVersion}/";
        var authBuilder = PublicClientApplicationBuilder.Create(clientId)
                        .WithAuthority(AadAuthorityAudience.AzureAdMultipleOrgs)
                        .WithRedirectUri(redirectUrl)
                        .Build();
        var scope = serviceUrl + "/user_impersonation";
        string[] scopes = { scope };
        // First try to get an authentication token from the cache using a hint.
        AuthenticationResult authBuilderResult=null;
        try
        {
            authBuilderResult = authBuilder.AcquireTokenSilent(scopes, username)
               .ExecuteAsync().Result;
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine(
                $"Error acquiring auth token from cache:{System.Environment.NewLine}{ex}");
            // Token cache request failed, so request a new token.
            try
            {
                if (username != string.Empty && password != string.Empty)
                {
                    // Request a token based on username/password credentials.
                    authBuilderResult = authBuilder.AcquireTokenByUsernamePassword(scopes, username, password)
                                .ExecuteAsync().Result;
                }
                else
                {
                    // Prompt the user for credentials and get the token.
                    authBuilderResult = authBuilder.AcquireTokenInteractive(scopes)
                                .ExecuteAsync().Result;
                }
            }
            catch (Exception msalex)
            {
                System.Diagnostics.Debug.WriteLine(
                    $"Error acquiring auth token with user credentials:{System.Environment.NewLine}{msalex}");
                throw;
            }
        }
        //Note that an Microsoft Entra ID access token has finite lifetime, default expiration is 60 minutes.
        authHeader = new AuthenticationHeaderValue("Bearer", authBuilderResult.AccessToken);
    }

    protected override Task<HttpResponseMessage> SendAsync(
              HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
    {
        request.Headers.Authorization = authHeader;
        return base.SendAsync(request, cancellationToken);
    }
}

En utilisant cette classe OAuthMessageHandler, la méthode Main simple ressemblerait à ceci.

class Program
{
    static void Main(string[] args)
    {
        try
        {
            //Get configuration data from App.config connectionStrings
            string connectionString = ConfigurationManager.ConnectionStrings["Connect"].ConnectionString;

            using (HttpClient client = SampleHelpers.GetHttpClient(connectionString, SampleHelpers.clientId,
                SampleHelpers.redirectUrl))
            {
                // Use the WhoAmI function
                var response = client.GetAsync("WhoAmI").Result;

                if (response.IsSuccessStatusCode)
                {
                    //Get the response content and parse it.
                    JObject body = JObject.Parse(response.Content.ReadAsStringAsync().Result);
                    Guid userId = (Guid)body["UserId"];
                    Console.WriteLine("Your UserId is {0}", userId);
                }
                else
                {
                    Console.WriteLine("The request failed with a status of '{0}'",
                                response.ReasonPhrase);
                }
                Console.WriteLine("Press any key to exit.");
                Console.ReadLine();
            }
        }
        catch (Exception ex)
        {
            SampleHelpers.DisplayException(ex);
            Console.WriteLine("Press any key to exit.");
            Console.ReadLine();
        }
    }
}

Les valeurs de chaîne de configuration ont été déplacées dans une chaîne de connexion de fichier App.config et le client HTTP est configuré dans la méthode GetHttpClient.

public static HttpClient GetHttpClient(string connectionString, string clientId, string redirectUrl, string version = "v9.2")
{
    string url = GetParameterValueFromConnectionString(connectionString, "Url");
    string username = GetParameterValueFromConnectionString(connectionString, "Username");
    string password = GetParameterValueFromConnectionString(connectionString, "Password");
    try
    {
        HttpMessageHandler messageHandler = new OAuthMessageHandler(url, clientId, redirectUrl, username, password,
                        new HttpClientHandler());

        HttpClient httpClient = new HttpClient(messageHandler)
        {
            BaseAddress = new Uri(string.Format("{0}/api/data/{1}/", url, version)),

            Timeout = new TimeSpan(0, 2, 0)  //2 minutes
        };

        return httpClient;
    }
    catch (Exception)
    {
        throw;
    }
}

Voir l’exemple Démarrage rapide amélioré pour le code complet.

Même si cet exemple utilise HttpClient.GetAsync plutôt que le SendAsync de substitution, il s’applique pour les méthodes HttpClient pour envoyer une requête.

Se connecter en tant qu’application

Certaines applications que vous allez créer n’ont pas pour but d’être exécutées de manière interactive par un utilisateur. Par exemple, vous pouvez souhaiter créer une application cliente Web qui peut exécuter des opérations sur les données Dataverse ou une application de console qui exécute une tâche programmée de toute sorte.

Tandis que vous exécutez ces scénarios avec les informations d’identification pour un utilisateur ordinaire, ce compte d’utilisateur doit utiliser une licence payée. Cette approche n’est pas recommandée.

Dans ces cas, vous pouvez créer un utilisateur d’application spécifique lié à une application enregistrée Microsoft Entra ID et utiliser une clé secrète configurée pour l’application ou télécharger un certificat X.509. Un autre avantage de cette approche consiste à ne pas utiliser une licence payée.

Exigences pour se connecter en tant qu’application

Pour se connecter en tant qu’application, vous avez besoin des éléments suivants :

  • Une application inscrite
  • Un utilisateur Dataverse lié à l’application enregistrée
  • Se connecter avec la clé secrète d’application ou une empreinte de certificat

Enregistrer votre application

Lors de l’enregistrement d’une application, vous suivez de nombreuses étapes identiques décrites dans Procédure pas à pas : Enregistrer une application avec Microsoft Entra ID, avec les exceptions suivantes :

  • Vous ne devez pas accorder l’autorisation Accéder à Dynamics 365 comme utilisateurs de l’organisation.

    Cette application est associée à un compte d’utilisateur spécifique.

  • Vous devez configurer une clé secrète pour l’enregistrement de l’application OU télécharger un certificat de clé publique.

Lors de l’enregistrement de l’application, sélectionnez la section Clés sur la page Paramètres.

Pour ajouter un certificat :

  1. Sélectionnez Télécharger la clé publique.
  2. Sélectionnez le fichier que vous voulez télécharger. Il doit être dans l’un des formats suivants : .cer, .pem, .crt.

Pour ajouter un mot de passe :

  1. Ajoutez une description pour votre clé.
  2. Sélectionnez une durée.
  3. Sélectionnez Enregistrer.

La colonne la plus à droite contient la valeur de la clé une fois que vous enregistrez les modifications apportées à la configuration. Veillez à copier la clé à utiliser dans votre code d’application cliente, puisqu’il n’est pas accessible une fois que vous quittez cette page.

Un compte utilisateur Dataverse lié à l’application enregistrée

Vous devez tout d’abord créer un rôle de sécurité personnalisé qui définira quel accès et quels privilèges ce compte aura dans l’organisation Dataverse. Pour plus d’informations : Créer ou configurer un rôle de sécurité personnalisé

Après avoir créé le rôle de sécurité personnalisé, vous devez créer le compte d’utilisateur qui l’utilisera.

Créer manuellement un utilisateur de l’application Dataverse

La procédure pour créer cet utilisateur est différente de celle de la création d’un utilisateur autorisé. Effectuez les opérations suivantes :

  1. Accédez à Paramètres > Sécurité > Utilisateurs

  2. Dans la liste déroulante Afficher, sélectionnez Utilisateurs d’application.

  3. Cliquez sur Nouveau. Vérifiez tandis que vous utilisez le formulaire Utilisateur de l’application.

    Si vous ne voyez pas les champs ID d’application, URI de l’ID d’application et ID d’objet Azure AD dans le formulaire, vous devez sélectionner le formulaire Utilisateur de l’application dans la liste :

    Sélectionner le formulaire Utilisateur de l′application.

  4. Ajoutez les valeurs appropriées aux champs :

    Champ valeur
    Nom d’utilisateur Nom pour l’utilisateur
    ID d’application Valeur de l’ID d’application de l’application enregistrée auprès de Microsoft Entra ID.
    Nom complet Nom de votre application.
    Adresse de messagerie principale Adresse de messagerie interne de l’utilisateur.

    Les champs URI de l’ID d’application et ID d’objet Azure AD sont verrouillés et vous ne pouvez pas définir les valeurs de ces champs.

    Lorsque vous créez cet utilisateur les valeurs de ces champs sont récupérées auprès de Microsoft Entra ID selon la valeur ID d’application lorsque vous enregistrez l’utilisateur.

  5. Associez l’utilisateur de l’application au rôle de sécurité personnalisé créé.

Se connecter à l’aide de la clé secrète de l’application

Si vous vous connectez à l’aide d’une clé secrète client et si vous utilisez le Microsoft.Xrm.Tooling.Connector.CrmServiceClient, vous pouvez utiliser le code suivant :

string SecretID = "00000000-0000-0000-0000-000000000000";
string AppID = "545ce4df-95a6-4115-ac2f-e8e5546e79af";
string InstanceUri = "https://yourorg.crm.dynamics.com";

string ConnectionStr = $@"AuthType=ClientSecret;
                        SkipDiscovery=true;url={InstanceUri};
                        Secret={SecretID};
                        ClientId={AppID};
                        RequireNewInstance=true";
using (ServiceClient svc = new ServiceClient(ConnectionStr))
{
    if (svc.IsReady)
    {
    //your code goes here
    }

}

Se connecter à l’aide d’une empreinte de certificat

Si vous vous connectez à l’aide d’un certificat et si vous utilisez le Microsoft.Xrm.Tooling.Connector.CrmServiceClient, vous pouvez utiliser le code suivant :

string CertThumbPrintId = "DC6C689022C905EA5F812B51F1574ED10F256FF6";
string AppID = "545ce4df-95a6-4115-ac2f-e8e5546e79af";
string InstanceUri = "https://yourorg.crm.dynamics.com";

string ConnectionStr = $@"AuthType=Certificate;
                        SkipDiscovery=true;url={InstanceUri};
                        thumbprint={CertThumbPrintId};
                        ClientId={AppID};
                        RequireNewInstance=true";
using (ServiceClient svc = new ServiceClient(ConnectionStr))
{
    if (svc.IsReady)
    {
    //your code goes here
    }

}

Voir aussi

Authentification auprès des services Web Microsoft Dataverse
Authentification des applications .NET Framework
Présentation de la bibliothèque d’authentification Microsoft

Notes

Pouvez-vous nous indiquer vos préférences de langue pour la documentation ? Répondez à un court questionnaire. (veuillez noter que ce questionnaire est en anglais)

Le questionnaire vous prendra environ sept minutes. Aucune donnée personnelle n’est collectée (déclaration de confidentialité).