Verwenden Sie die OAuth Authentifizierung mit Microsoft Dataverse
OAuth 2.0 ist das Industriestandardprotokoll für die Autorisierung. Nachdem Anwendungsbenutzer ihre Anmeldeinformationen zur Authentifizierung angegeben haben, OAuth wird ermittelt, ob sie zum Zugriff auf die Ressourcen berechtigt sind.
Clientanwendungen müssen die Verwendung von OAuth unterstützen, um über die Web-API auf Daten zuzugreifen. OAuth ermöglicht Zwei-Faktor-Authentifizierung (2FA) oder zertifikatsbasierte Authentifizierung für Server-zu-Server-Anwendungsszenarien.
OAuth erfordert einen Identitätsanbieter zur Authentifizierung. Für Dataverse ist der Identitätsanbieter Microsoft Entra ID. Verwenden Sie zur Authentifizierung mit einem Microsoft-Arbeits- oder Schulkonto die Microsoft Authentication Library (MSAL).
Anmerkung
In diesem Thema werden allgemeine Konzepte im Zusammenhang mit der Verbindung zur Dataverse Verwendung OAuth mit Authentifizierungsbibliotheken vorgestellt. In diesem Inhalt geht es darum, wie ein Entwickler Verbinden verwenden kann, Dataverse jedoch nicht um die Funktionsweise OAuth oder die 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 Verbinden mit OAuth verwenden, müssen Sie zuerst eine Anwendung in Ihrem Microsoft Entra ID-Mandanten registrieren. Wie Sie Ihre App registrieren sollten, hängt von der Art der App ab, die Sie erstellen möchten.
Beginnen Sie in jedem Fall mit den grundlegenden Schritten zum Registrieren einer App, die im Artikel Schnellstart: Registrieren einer Anwendung bei der Microsoft Identity Platform beschrieben sind. Dataverse Spezifische Anweisungen finden Sie unter Walkthrough: Registrieren Sie eine App mit der 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 Clientanwendung , die den gesamten Code auf einem Webserver ausführt. Benutzeragent-basierter Client Ein Typ von Clientanwendung , die Code von einem Webserver herunterlädt und in einem Benutzeragenten (z. B. einem Webbrowser) ausführt, etwa eine Single Page Application (SPA). |
einheitlich | Ein Typ von Clientanwendung , die nativ auf einem Gerät installiert wird. |
Wenn Sie Auswählen Web-App/API verwenden, müssen Sie eine Anmelde-URL angeben. Das ist die URL, an die Microsoft Entra ID die Authentifizierung Antwort sendet, einschließlich eines Tokens, wenn die Authentifizierung erfolgreich war. Während Sie eine App entwickeln, wird diese URL normalerweise auf https://localhost/appname:[port]
gesetzt, damit 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 Auswählen Native verwenden, müssen Sie eine Umleitungs-URI angeben. Diese URL ist eine eindeutige Kennung, zu der Microsoft Entra ID den Benutzeragenten in einer OAuth 2.0-Anfrage umleitet. Diese URL ist normalerweise ein Wert im Format 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.
Spezifische Schritte zum Festlegen von Berechtigungen finden Sie unter Eine App mit der Microsoft Entra ID registrieren.
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 Anwendungstyp Web-App/API registriert sind, können Sie Geheimnisse konfigurieren. Diese werden mithilfe des Bereichs Schlüssel unter API-Zugriff in den Einstellungen für die App-Registrierung festgelegt.
Für beide Anwendungsarten können Sie ein Zertifikat hochladen.
Weitere Informationen: Verbinden als App
Authentifizierungsbibliotheken verwenden, um eine Verbindung herzustellen
Verwenden Sie eine der von Microsoft unterstützten Microsoft Entra Clientbibliotheken zur ID-Authentifizierung, um Verbinden zu Dataverse z. B. die Microsoft Authentication Library (MSAL). Diese Bibliothek ist für verschiedene Plattformen verfügbar, wie in den bereitgestellten Links beschrieben:
Anmerkung
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 zur Authentifizierung demonstriert, Dataverse finden Sie im QuickStart-Beispiel.
.NET-Clientbibliotheken
Dataverse unterstützt Anwendungsauthentifizierung mit der Web-API Endpunkt unter Verwendung des Protokolls OAuth 2.0. Verwenden Sie für Ihre benutzerdefinierten .NET-Anwendungen MSAL für die Anwendungsauthentifizierung mit dem Web-API-Endpunkt.
Dataverse SDK für .NET umfasst Clientklassen CrmServiceClient und ServiceClient zur Handhabung der Authentifizierung. Die CrmServiceClient
Klasse verwendet derzeit ADAL zur 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. Zum Abrufen des Tokens sind nur wenige Codezeilen erforderlich. Außerdem sind nur wenige Zeilen erforderlich, um einen HttpClient für die Ausführung einer Anforderung zu konfigurieren.
Wichtig
Verwenden Sie für einen öffentlichen Client den Bereich „<environment-url>/user_impersonation“, wie im Beispielcode dieses Artikels gezeigt. Verwenden Sie für einen vertraulichen Client den Bereich „<environment-url>/.default“.
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 QuickStart Beispiel 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 für folgen dar, da token
in etwa einer Stunde abläuft. MSAL-Bibliotheken speichern das Token für Sie im Cache und aktualisieren es 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 besteht darin, eine von DelegatingHandler abgeleitete Klasse zu implementieren, die an den Konstruktor von HttpClient übergeben wird. Mit diesem Handler können Sie die HttpClient.SendAsync Methode überschreiben, sodass Zugriffstoken durch die AcquireToken*
Methodenaufrufe bei jeder vom HTTP-Client gesendeten Anforderung aktualisiert wird.
Das Folgende ist ein Beispiel einer benutzerdefinierten Klasse, die von DelegatingHandler abgeleitet ist. Dieser Code stammt aus dem Beispiel Erweiterter Schnellstart , 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);
}
}
Mit dieser OAuthMessageHandler
Klasse würde die einfache Main
Methode wie folgt aussehen.
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 Methode GetHttpClient
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;
}
}
Den vollständigen Code finden Sie im Beispiel Erweiterter Schnellstart .
Auch wenn in diesem Beispiel HttpClient.GetAsync anstelle des überschriebenen SendAsync verwendet wird, gilt es für alle HttpClient Methoden, die eine Anfrage 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 mit einer 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
Beim Registrieren einer App folgen führen Sie viele der in Walkthrough: Registrieren einer App mit Microsoft Entra ID beschriebenen Schritte aus, mit folgenden Ausnahmen:
Sie müssen die Berechtigung Auf Dynamics 365 als Organisationsbenutzer zugreifen nicht 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.
Sie können Anmeldeinformationen in Ihrer App-Registrierung unter Verwalten>Zertifikate und Geheimnisse erstellen oder anzeigen.
So fügen Sie ein Zertifikat (öffentlichen Schlüssel) hinzu:
- Klicken Sie auf der Registerkarte Zertifikate auf Auswählen Zertifikat hochladen.
- Wählen Sie die Datei aus, die Sie hochladen möchten. Es muss einer der folgenden Dateitypen sein: .cer,.pem,.crt.
- Geben Sie eine Beschreibungen an.
- Wählen Sie Hinzufügen aus.
So fügen Sie ein Client-Geheimnis (Anwendungskennwort) hinzu:
- Fügen Sie auf der Registerkarte Clientgeheimnisse eine Beschreibung für Ihr Clientgeheimnis hinzu.
- Auswählen eine Ablaufzeitspanne.
- Wählen Sie Hinzufügen aus.
Wichtig
Nachdem Sie die Konfigurationsänderungen gespeichert haben, wird ein geheimer Wert angezeigt. Denken Sie daran, den geheimen Wert zur Verwendung in Ihrem Client-Anwendungscode zu kopieren, da auf diesen Wert nicht mehr zugegriffen werden kann, sobald Sie die Seite verlassen.
Weitere Informationen: Anmeldeinformationen hinzufügen
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 Informationen: Erstellen oder konfigurieren Sie ein benutzerdefiniertes Sicherheitsrolle
Nachdem Sie die benutzerdefinierte Sicherheitsrolle erstellt haben, müssen Sie das Benutzerkonto erstellen, das sie verwenden wird.
Manuelles Erstellen eines Dataverse-Anwendungsbenutzers
Das Verfahren zum Erstellen eines Anwendungsbenutzers finden Sie im Artikel „Verwalten“: Power Platform Einen Anwendungsbenutzer erstellen .
Nachdem Sie einen Anwendungsbenutzer erstellt haben, verknüpfen Sie den Anwendungsbenutzer mit der benutzerdefinierten Kennung Sicherheitsrolle, die Sie erstellt haben.
Verbindung über das Anwendungsgeheimnis herstellen
Wenn Sie die Verbindung unter Verwendung eines geheimen Clientschlüssels herstellen und Microsoft.Xrm.Tooling.Connector.CrmServiceClient verwenden, 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 eine Verbindung mithilfe eines Zertifikats herstellen und Microsoft.Xrm.Tooling.Connector.CrmServiceClient verwenden, 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
Authentifizieren von .NET Framework-Anwendungen
Übersicht über die Microsoft Authentication Library