Utiliser OAuth l’authentification avec Microsoft Dataverse

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

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

OAuth nécessite un fournisseur d’identité pour l’authentification. Pour Dataverse, le fournisseur d’identité est Microsoft Entra ID. Pour vous authentifier à l’aide d’un compte professionnel ou scolaire Microsoft, utilisez la bibliothèque d’authentification Microsoft (MSAL).

Note

Ce rubrique présentera les concepts communs liés à la connexion à Dataverse l’aide OAuth des bibliothèques d’authentification. Ce contenu se concentrera sur la manière dont un développeur peut Connecter Dataverse mais pas sur le fonctionnement interne de OAuth ou des bibliothèques. Pour des informations complètes relatives à l’authentification, consultez la documentation Microsoft Entra ID. Qu’est-ce que l’authentification ? est un bon point de départ.

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.

Inscription de l’application

Lorsque vous utilisez Connecter OAuth, vous devez d’abord enregistrer une application dans votre locataire 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écrites dans l’article : Démarrage rapide : enregistrer une application auprès de la plateforme d’identité Microsoft. Pour des instructions spécifiques, consultez la procédure pas à pas : enregistrer une application avec un ID. Dataverse Microsoft Entra

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
Un type d’ application cliente qui exécute tout le code sur un serveur Web.

Client basé sur un agent utilisateur
Un type d’ application cliente qui télécharge du code à partir d’un serveur Web et s’exécute dans un agent utilisateur (par exemple, un navigateur Web), comme une application à page unique (SPA).
natif Un type d’ application cliente installée nativement sur un appareil.

Lorsque vous utilisez une application Web/API Sélectionner /vous devez fournir une URL de connexion qui est l’URL où l’ID envoie l’authentification réponse, y compris un jeton si l’authentification a réussi. Microsoft Entra 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 utilisez Sélectionner Natif, vous devez fournir un URI de redirection. Cette URL est un identifiant unique vers lequel Microsoft Entra ID redirigera l’agent utilisateur dans une OAuth requête 2.0. Cette URL est généralement une valeur formatée comme suit : 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 permettant de définir des autorisations, consultez Enregistrer une application avec Microsoft Entra ID.

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 des secrets. Ceux-ci sont définis à l’aide de la zone Clés sous Accès API dans les Paramètres pour l’enregistrement de l’application.

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

Plus d’informations : Connecter en tant qu’application

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

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

Note

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 démontre 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 l’API Web point de terminaison en utilisant le 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.

Dataverse Le SDK pour .NET inclut les classes client CrmServiceClient et ServiceClient pour gérer l’authentification. La classe utilise actuellement ADAL pour l’authentification tandis que elle utilise MSAL. CrmServiceClient ServiceClient 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. Obtenir le jeton ne nécessite que quelques lignes de code, et seulement quelques lignes supplémentaires pour configurer un 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 de « <environment-url>/.default".

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 QuickStart .

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 modèle pour suivre car le token expirera dans environ une heure. Les bibliothèques MSAL mettront en cache le jeton pour vous et l’actualiseront à chaque fois que la méthode est appelée. 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 est d’implémenter une classe dérivée de DelegatingHandler qui sera transmise au constructeur de HttpClient. Ce gestionnaire vous permettra de remplacer la méthode HttpClient.SendAsync afin que le token soit actualisé par les appels de méthode AcquireToken* à chaque requête envoyée par le client Http.

Voici un exemple d’une classe personnalisée dérivée de DelegatingHandler. Ce code est extrait de l’exemple Enhanced QuickStart qui utilise la 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 OAuthMessageHandler classe, la méthode simple Main 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 la 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;
    }
}

Consultez l’exemple Enhanced QuickStart pour obtenir le code complet.

Même si cet exemple utilise HttpClient.GetAsync plutôt que le SendAsync remplacé, il s’appliquera à toutes les HttpClient méthodes qui envoient 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écial lié à une application enregistrée avec un ID et utiliser soit une clé secrète configurée pour l’application, soit télécharger un certificat X.509. Microsoft Entra 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 la plupart des étapes décrites dans Procédure pas à pas : Enregistrer une application avec Microsoft Entra ID, avec les exceptions suivantes :

  • Vous n’avez pas besoin d’accorder l’autorisation Accéder à Dynamics 365 en tant qu’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.

Vous pouvez créer ou afficher des informations d’identification dans l’enregistrement de votre application sous Gérer>Certificats et secrets.

Pour ajouter un certificat (clé publique) :

  1. Dans l’onglet Certificats , Sélectionner Télécharger le certificat.
  2. Sélectionnez le fichier que vous voulez télécharger. Il doit être dans l’un des formats suivants : .cer, .pem, .crt.
  3. Fournissez une description.
  4. Sélectionnez Ajouter.

Pour ajouter un secret client (mot de passe d’application) :

  1. Dans l’onglet Secrets client , ajoutez une description pour votre secret client.
  2. Sélectionner une période d’expiration.
  3. Sélectionnez Ajouter.

Important

Après avoir enregistré les modifications de configuration, une valeur secrète s’affiche. Assurez-vous de copier la valeur secrète à utiliser dans le code de votre application cliente, car cette valeur n’est pas accessible une fois que vous avez quitté la page.

Plus d’informations : Ajouter des informations d’identification

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. 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 de création d’un utilisateur d’application se trouve dans l’article Administrer Power Platform  : Créer un utilisateur d’application.

Après avoir créé un utilisateur d’application, associez-le au rôle de sécurité personnalisé que vous avez créé.

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

Si vous vous connectez à l’aide d’un secret client et que vous utilisez le Microsoft.Xrm.Tooling.Connector.CrmServiceClient , vous pouvez utiliser un code comme celui-ci :

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 utilisez le Microsoft.Xrm.Tooling.Connector.CrmServiceClient , vous pouvez utiliser un code comme celui-ci :

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 avec les services Web Microsoft Dataverse
Authentification des applications suivre
Présentation de la bibliothèque d’authentification Microsoft