OAuth-Authentifizierung mit Microsoft Dataverse verwenden

OAuth 2.0 ist das branchenübliche Protokoll für die Autorisierung. Nachdem Anwendungsbenutzende Anmeldeinformationen zur Authentifizierung angegeben haben, bestimmt OAuth, ob sie zum Zugriff auf die Ressourcen berechtigt sind.

Client-Anwendungen müssen die Verwendung von OAuth für den Datenzugriff über die Web-API unterstützen. OAuth ermöglicht eine Zwei-Faktor-Authentifizierung (2FA) oder eine zertifikatsbasierte Authentifizierung für Server-zu-Server-Anwendungsszenarien.

OAuth benötigt für die Authentifizierung einen Identitätsanbieter. Für Dataverse ist der Identitätsanbieter Microsoft Entra ID. Um sich mit einem Geschäfts-, Schul- oder Unikonto von Microsoft zu authentifizieren, nutzen Sie die Microsoft Authentication Library (MSAL).

Hinweis

In diesem Thema werden allgemeine Konzepte für die Anbindung an Dataverse mit OAuth mit den Authentifizierungsbibliotheken vorgestellt. Dieser Inhalt konzentriert sich darauf, wie ein Entwickler eine Verbindung zu Dataverse herstellen kann, nicht aber auf die Funktionsweise von OAuth oder den Bibliotheken. Ausführliche Informationen zur Authentifizierung finden Sie in der Microsoft Entra ID-Dokumentation. Was ist Authentifizierung ist ein guter Ausgangspunkt.

Die von uns zur Verfügung gestellten Muster sind mit entsprechenden Registrierungswerten vorkonfiguriert, so dass Sie sie ohne Generierung einer eigenen App-Registrierung ausführen können. Wenn Sie eigene Apps veröffentlichen, müssen Sie eigene Registrierungswerte verwenden.

App-Registrierung

Wenn Sie sich über OAuth verbinden, müssen Sie zunächst eine Anwendung in Ihrem Microsoft Entra ID-Mandant registrieren. Wie Sie Ihre App registrieren sollten, hängt von der Art der App ab, die Sie erstellen möchten.

Beginnen Sie in allen Fällen mit den grundlegenden Schritten zur Registrierung einer App, wie im Artikel beschrieben: Schnellstart: Eine Anwendung bei der Microsoft Identity Platform registrieren. Für Dataverse-spezifische Anweisungen siehe Exemplarische Vorgehensweise: Registrieren einer App mit Microsoft Entra ID.

Die Entscheidungen, die Sie in diesem Schritt treffen müssen, hängen hauptsächlich von der Wahl des Anwendungstyps ab (siehe unten).

Arten der App-Registrierung

Wenn Sie eine App mit Microsoft Entra ID registrieren, ist eine der Entscheidungen, die Sie treffen müssen, der Anwendungstyp. Es gibt zwei Arten von Anwendungen, die Sie registrieren können:

Anwendungstyp Beschreibung
Web-App / API Webclient
Eine Art von Client-Anwendung, die den gesamten Code auf einem Webserver ausführt.

Benutzer-Agent-basierter Client
Ein Typ von Client-Anwendung, der Code von einem Webserver herunterlädt und innerhalb eines Benutzeragenten (z.B. eines Webbrowsers) ausgeführt wird, wie beispielsweise eine Single Page Application (SPA).
einheitlich EinTyp von Client-Anwendung, der nativ auf einem Gerät installiert wird.

Wenn Sie Web-App/API auswählen, müssen Sie eine Anmelde-URL angeben, die die URL ist, unter der Microsoft Entra ID die Authentifizierungsantwort sendet, einschließlich eines Token, wenn die Authentifizierung erfolgreich war. Während Sie eine App entwickeln, lautet diese URL in der Regel auf https://localhost/appname:[port], sodass Sie Ihre App lokal entwickeln und debuggen können. Wenn Sie Ihre App veröffentlichen, müssen Sie diesen Wert auf die veröffentlichte URL der App ändern.

Wenn Sie Native wählen, müssen Sie eine Umleitungs-URI bereitstellen. Diese URL ist eine eindeutige Kennung, an die Microsoft Entra ID den Benutzer-Agenten in einer OAuth 2.0-Anfrage weiterleitet. Diese URL ist normalerweise ein Wert, der so formatiert ist: app://<guid>.

Zugriff auf Dataverse geben

Wenn Ihre Anwendung ein Client ist, der es dem authentifizierten Benutzenden ermöglicht, Vorgänge auszuführen, müssen Sie die Anwendung so konfigurieren, dass die Access Dynamics 365 als Berechtigung von Organisationsbenutzenden vergeben wird.

Konkrete Schritte zum Festlegen von Berechtigungen finden Sie unter Registrieren einer App bei Microsoft Entra ID.

Wenn Ihre Anwendung die Server-zu-Server-(S2S-)Authentifizierung verwendet, ist dieser Schritt nicht erforderlich. Diese Konfiguration erfordert einen bestimmten Systembenutzenden und die Vorgänge werden von diesem Benutzerkonto und nicht von jedem Benutzenden durchgeführt, die authentifiziert werden müssen.

Verwenden von geheimen Clientschlüsseln und Zertifikaten

Für Server-zu-Server-Szenarien wird es kein interaktives Benutzerkonto zur Authentifizierung geben. In diesen Fällen müssen Sie einige Mittel bereitstellen, um zu bestätigen, dass die Anwendung vertrauenswürdig ist. Dies geschieht über geheime Clientschlüssel oder Zertifikate.

Für Apps, die mit dem Applikationstyp Web App /API registriert sind, können Sie Geheimnisse konfigurieren. Diese werden über den Bereich Schlüssel unter API Zugriff in den Einstellungen für die App-Registrierung eingestellt.

Für beide Anwendungsarten können Sie ein Zertifikat hochladen.

Weitere Informationen: Als App verbinden

Authentifizierungsbibliotheken verwenden, um eine Verbindung herzustellen

Verwenden Sie eine der von Microsoft unterstützten Microsoft Entra ID-Authentifizierungs-Clientbibliotheken, um eine Verbindung zu Dataverse herzustellen, z. B. Microsoft Authentication Library (MSAL). Diese Bibliothek ist für verschiedene Plattformen verfügbar, wie in den bereitgestellten Links beschrieben:

Hinweis

Azure Active Directory-Authentifizierungsbibliothek (ADAL) enthält aktiv keine Updates mehr und soll nur noch bis Juni 2022 unterstützt werden. MSAL ist die empfohlene Authentifizierungsbibliothek für Projekte.

Ein Codebeispiel, das die Verwendung von MSAL-Bibliotheken für die Authentifizierung mit Dataverse demonstriert, finden Sie unter Schnellstartbeispiel.

.NET-Clientbibliotheken

Dataverse unterstützt die Anwendungsauthentifizierung mit dem Web-API-Endpunkt unter Verwendung des OAuth 2.0-Protokolls. Verwenden Sie für Ihre benutzerdefinierten .NET-Anwendungen MSAL für die Anwendungsauthentifizierung mit dem Web-API-Endpunkt.

Dataverse SDK für .NET enthält Clientklassen CrmServiceClient und ServiceClient, um Authentifizierung zu behandeln. Die CrmServiceClient-Klasse verwendet derzeit ADAL für die Authentifizierung während ServiceClient MSAL verwendet. Durch das Schreiben Ihres Anwendungscodes zur Verwendung dieser Clients entfällt die Notwendigkeit, die Authentifizierung direkt zu verwalten. Beide Clients arbeiten mit den SDK- und Web-API-Endpunkten.

Verwenden Sie den AccessToken für Ihre Anfragen.

Der Sinn der Verwendung der Authentifizierungsbibliotheken besteht darin, ein Zugriffstoken zu erhalten, das Sie in Ihre Anfragen aufnehmen können. Das Abrufen des Tokens erfordert nur ein paar Zeilen Code und nur ein paar weitere Zeilen, um einen HttpClient zur Ausführung einer Anfrage zu konfigurieren.

Wichtig

Verwenden Sie, wie im Beispielcode dieses Artikels gezeigt, einen „<environment-url>/user_impersonation“-Bereich als öffentlichen Client. Verwenden Sie als vertraulichen Client einen „<environment-url>/.default“-Bereich.

Ein einfaches Beispiel

Im Folgenden finden Sie die Mindestmenge an Code, die benötigt wird, um eine einzelne Web-API-Anfrage auszuführen, aber es ist nicht der empfohlene Ansatz. Beachten Sie, dass dieser Code die MSAL-Bibliothek verwendet und aus dem oben erwähnten Beispiel Schnellstart stammt.

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;

Dieser einfache Ansatz stellt kein gutes Muster dar, da der token in etwa einer Stunde abläuft. MSAL-Bibliotheken speichern den Token für Sie und aktualisieren ihn bei jedem Aufruf der AcquireTokenInteractive-Methode. In diesem einfachen Beispiel wird der Token jedoch nur einmal erworben.

Beispiel zur Demonstration eines delegierten Meldungshandlers

Der empfohlene Ansatz ist die Implementierung einer von DelegatingHandler abgeleiteten Klasse, die an den Konstruktor des HttpClient übergeben wird. Dieser Handler ermöglicht es Ihnen, die HttpClient.SendAsync zu überschreiben. Methode, sodass der Zugriffstoken bei jeder vom HTTP-Client gesendeten Anforderung von Aufrufen der AcquireToken*-Methode aktualisiert wird.

Das Folgende ist ein Beispiel für eine benutzerdefinierte Klasse, die von DelegatingHandler abgeleitet ist. Dieser Code stammt aus dem Beispiel des verbesserten Schnellstarts, das die MSAL-Authentifizierungsbibliothek verwendet.

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);
    }
}

Wenn Sie diese OAuthMessageHandler-Klasse verwendet, sieht die einfach Main-Methode so aus.

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();
        }
    }
}

Die Werte der Konfigurationszeichenfolge wurden in eine Verbindungszeichenfolge der Datei App.config verschoben, und der HTTP-Client wird in der GetHttpClient-Methode konfiguriert.

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;
    }
}

Weitere Informationen zum vollständigen Coden finden Sie im Beispiel für den verbesserten Schnellstart.

Auch wenn dieses Beispiel HttpClient.GetAsync verwendet. statt des überschriebenen SendAsync, gilt es für jede der HttpClient-Methoden, die eine Anforderung senden.

Als App verbinden

Einige Anwendungen, die Sie erstellen werden, sind nicht dazu gedacht, von einem Benutzer interaktiv ausgeführt zu werden. Beispielsweise können Sie eine Web-Client-Anwendung erstellen, die Operationen mit Dataverse-Daten ausführen kann, oder eine Konsolenanwendung, die eine geplante Aufgabe in irgendeiner Form ausführt.

Während Sie diese Szenarien mit Anmeldeinformationen für einen normalen Benutzer erreichen könnten, müsste dieses Benutzerkonto eine kostenpflichtige Lizenz verwenden. Dies ist nicht die empfohlene Verfahrensweise.

In diesen Fällen können Sie einen speziellen Anwendungsbenutzer erstellen, der an eine von Microsoft Entra ID registrierte Anwendung gebunden ist, und entweder ein für die App konfiguriertes Schlüsselgeheimnis verwenden oder ein X.509-Zertifikat hochladen. Ein weiterer Vorteil dieses Ansatzes ist, dass er keine kostenpflichtige Lizenz verbraucht.

Anforderungen für die Verbindung als App

Um sich als App zu verbinden, benötigen Sie:

  • Eine registrierte App
  • Einen Dataverse-Benutzer, der an die registrierte App gebunden ist
  • Verbinden Sie sich entweder über das Anwendungsgeheimnis oder über einen Zertifikat-Fingerabdruck.

Registrieren Sie die App

Wenn Sie eine App registrieren, befolgen Sie die meisten der Schritte, die unter Exemplarische Vorgehensweise: Registrieren einer App bei Microsoft Entra ID beschrieben sind, mit den folgenden Ausnahmen:

  • Sie müssen die Berechtigung Zugriff auf Dynamics 365 als Organisationsbenutzer erteilen.

    Diese Anwendung ist an ein bestimmtes Benutzerkonto gebunden.

  • Sie müssen ein Geheimnis für die App-Registrierung konfigurieren ODER ein Public-Key-Zertifikat hochladen.

Wählen Sie während der Registrierung der App den Abschnitt Schlüssel auf der Seite Einstellungen.

So fügen Sie ein Zertifikat hinzu:

  1. Wählen Sie Öffentlichen Schlüssel hochladen aus.
  2. Wählen Sie die Datei aus, die Sie hochladen möchten. Es muss einer der folgenden Dateitypen sein: .cer,.pem,.crt.

So fügen Sie ein Passwort hinzu:

  1. Fügen Sie eine Beschreibung für den Schlüssel hinzu.
  2. Wählen Sie eine Dauer aus.
  3. Wählen Sie Speichern aus.

Die Spalte ganz rechts enthält den Schlüsselwert, nachdem Sie die Konfigurationsänderungen gespeichert haben. Achten Sie darauf, den Schlüssel für die Verwendung in Ihrem Client-Anwendungscode zu kopieren, da er nach dem Verlassen dieser Seite nicht mehr zugänglich ist.

Dataverse-Benutzerkonto, das an die registrierte App gebunden ist

Das erste, was Sie tun müssen, ist, eine benutzerdefinierte Sicherheitsrolle zu erstellen, die definiert, welchen Zugriff und welche Rechte dieses Konto innerhalb der Dataverse-Organisationen hat. Weitere Information finden Sie unter Erstellen oder Konfigurieren einer benutzerdefinierten Sicherheitsrolle

Nachdem Sie die benutzerdefinierte Sicherheitsrolle erstellt haben, müssen Sie das Benutzerkonto erstellen, das sie verwenden wird.

Manuelles Erstellen eines Dataverse-Anwendungsbenutzers

Die Vorgehensweise, um diesen Benutzer zu erstellen, unterscheidet sich vom Erstellen eines lizenzierten Benutzers. Verwenden Sie die folgenden Schritte:

  1. Gehen Sie zu Einstellungen > Sicherheit > Benutzer

  2. Klicken Sie in der Dropdownliste der Ansichten auf Anwendungsbenutzer.

  3. Klicken Sie auf Neu. Überprüfen Sie dann, ob Sie das Formular Anwendungsbenutzer verwenden.

    Wenn Sie die Felder Anwendungs-ID, URI der Anwendungs-ID und Azure AD Objekt-ID im Formular nicht sehen, müssen Sie aus der Liste Anwendungsbenutzer auswählen:

    Anwendungsbenutzerformular auswählen.

  4. Hinzufügen der entsprechenden Werte zu den Feldern:

    Feld Wert
    Benutzername Ein Name für den Benutzer
    Anwendungs-ID Der Anwendungs-ID-Wert für die Anwendung, die bei Microsoft Entra ID registriert ist.
    Vollständiger Name Der Name Ihrer Anwendung.
    Primäre E-Mail-Adresse Die E-Mail-Adresse des Benutzers.

    Die Felder URI der Anwendungs-ID und Azure AD Objekt-ID sind gesperrt und können Sie keine Werte für diese Felder festlegen.

    Wenn Sie diesen Benutzer erstellen, werden die Werte für diese Felder aus Microsoft Entra ID basierend auf dem Wert der Anwendungs-ID abgerufen, wenn Sie den Benutzer speichern.

  5. Ordnen Sie den Anwendungsbenutzer der von Ihnen erstellten benutzerdefinierten Sicherheitsrolle zu.

Verbindung über das Anwendungsgeheimnis herstellen

Wenn Sie sich mit einem geheimen Clientschlüssel und mit der Microsoft.Xrm.Tooling.Connector.CrmServiceClient verbinden, können Sie Code wie den folgenden verwenden:

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
    }

}

Verbindung über einen Zertifikatsfingerabdruck herstellen

Wenn Sie sich mit einem Zertifikat und mit der Microsoft.Xrm.Tooling.Connector.CrmServiceClient verbinden, können Sie Code wie den folgenden verwenden:

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
    }

}

Siehe auch

Authentifizierung mit Microsoft Dataverse-Webdiensten
Authentifizierung von .NET Framework-Anwendungen
Übersicht über die Microsoft-Authentifizierungsbibliothek

Hinweis

Können Sie uns Ihre Präferenzen für die Dokumentationssprache mitteilen? Nehmen Sie an einer kurzen Umfrage teil. (Beachten Sie, dass diese Umfrage auf Englisch ist.)

Die Umfrage dauert etwa sieben Minuten. Es werden keine personenbezogenen Daten erhoben. (Datenschutzbestimmungen).