Tutorial: Anmelden von Benutzern und Aufrufen von Microsoft Graph in der WPF-Desktop-App (Windows Presentation Foundation)

In diesem Tutorial erstellen Sie eine native Windows Desktop .NET-App (XAML-App), die Benutzer*innen anmeldet und ein Zugriffstoken abruft, um die Microsoft Graph-API aufzurufen.

Am Ende dieses Leitfadens kann Ihre Anwendung eine geschützte API aufrufen, die persönliche Konten (outlook.com, live.com und andere) verwendet. Die Anwendung kann auch Geschäfts-, Schul- und Unikonten aus Unternehmen oder Organisationen nutzen, die Microsoft Entra ID verwenden.

Dieses Tutorial umfasst folgende Punkte:

  • Erstellen eines Windows Presentation Foundation (WPF) -Projekts in Visual Studio
  • Installieren der Microsoft Authentication Library (MSAL) für .NET
  • Registrieren der Anwendung
  • Hinzufügen von Code zur Unterstützung der Benutzeranmeldung und -abmeldung
  • Hinzufügen von Code zum Aufrufen der Microsoft Graph-API
  • Testen der App

Voraussetzungen

Funktionsweise der über diesen Leitfaden generierten Beispiel-App

Screenshot of how the sample app generated by this tutorial works.

Die in diesem Leitfaden erstellte Beispielanwendung ermöglicht einer Windows Desktop-Anwendung das Abfragen der Microsoft Graph-API oder einer Web-API, die Token von einem Microsoft Identity Platform-Endpunkt akzeptiert. In diesem Szenario fügen Sie HTTP-Anforderungen ein Token über den Autorisierungsheader hinzu. Tokenabruf und -erneuerung werden von der Microsoft-Authentifizierungsbibliothek (Microsoft Authentication Library, MSAL) gehandhabt.

Verarbeiten des Beziehens von Token für den Zugriff auf geschützte Web-APIs

Nach der Authentifizierung des Benutzers empfängt die Beispielanwendung ein Token, mit dem eine per Microsoft Identity Platform geschützte Microsoft Graph-API oder Web-API abgefragt werden kann.

APIs wie Microsoft Graph erfordern ein Token, um den Zugriff auf bestimmte Ressourcen zu ermöglichen. Ein Token ist beispielsweise erforderlich, um das Profil eines Benutzers zu lesen, auf den Kalender eines Benutzers zuzugreifen oder eine E-Mail zu senden. Ihre Anwendung kann unter Verwendung von MSAL ein Zugriffstoken anfordern, um auf diese Ressourcen durch Angeben von API-Bereichen zuzugreifen. Dieses Zugriffstoken wird dann dem HTTP-Autorisierungsheader für jeden Aufruf hinzugefügt, der für die geschützte Ressource erfolgt.

MSAL nimmt Ihrer Anwendung die Verwaltung der Zwischenspeicherung und Aktualisierung von Zugriffstoken ab.

NuGet-Pakete

In dieser Anleitung werden die folgenden NuGet-Pakete verwendet:

Bibliothek BESCHREIBUNG
Microsoft.Identity.Client Microsoft Authentication Library (MSAL.NET)

Einrichten des Projekts

In diesem Abschnitt erstellen Sie ein neues Projekt, um zu veranschaulichen, wie Sie eine Windows Desktop .NET-Anwendung (XAML) so in Anmelden mit Microsoft integrieren können, dass sie Web-APIs abfragen kann, die ein Token erfordern.

Die Anwendung, die Sie erstellen werden, enthält eine Schaltfläche, die die Microsoft Graph-API aufruft, einen Bereich zum Anzeigen der Ergebnisse sowie eine Schaltfläche zum Abmelden.

Hinweis

Möchten Sie stattdessen das Visual Studio-Projekt dieses Beispiels herunterladen? Laden Sie ein Projekt herunter, und fahren Sie mit dem Konfigurationsschritt fort, um das Codebeispiel vor der Ausführung zu konfigurieren.

Führen Sie die folgenden Schritte zum Erstellen der Anwendung aus:

  1. Öffnen Sie Visual Studio.
  2. Klicken Sie im Startfenster auf Neues Projekt erstellen.
  3. Wählen Sie in der Dropdownliste Alle Sprachedie Option C# aus.
  4. Suchen Sie nach der Vorlage WPF-App (.NET Framework), wählen Sie sie aus, und wählen Sie anschließend „Weiter“ aus.
  5. Geben Sie im Feld Projektname einen Namen wie Win-App-calling-MsGraph ein.
  6. Wählen Sie einen Speicherort für das Projekt aus, oder übernehmen Sie die Standardoption.
  7. Wählen Sie im Framework die Option .NET Framework 4.8 aus.
  8. Klicken Sie auf Erstellen.

Hinzufügen von MSAL zu Ihrem Projekt

  1. Klicken Sie in Visual Studio auf Tools>NuGet-Paket-Manager>Paket-Manager-Konsole.

  2. Fügen Sie im Fenster „Paket-Manager-Konsole“ den folgenden Azure PowerShell-Befehl ein:

    Install-Package Microsoft.Identity.Client -Pre
    

Anwendung registrieren

Tipp

Die Schritte in diesem Artikel können je nach dem Portal, mit dem Sie beginnen, geringfügig variieren.

Führen Sie die folgenden Schritte aus, um Ihre Anwendung zu registrieren und zu konfigurieren:

  1. Melden Sie sich beim Microsoft Entra Admin Center mindestens mit der Rolle Anwendungsentwickler an.
  2. Wenn Sie Zugriff auf mehrere Mandanten haben, verwenden Sie das Symbol für Einstellungen im oberen Menü, um zum Mandanten zu wechseln, in dem Sie die Anwendung über das Menü Verzeichnisse + Abonnements registrieren möchten.
  3. Browsen Sie zu Identität>Anwendungen>App-Registrierungen.
  4. Wählen Sie Neue Registrierung aus.
  5. Geben Sie unter Name einen Namen für Ihre Anwendung ein (beispielsweise Win-App-calling-MsGraph). Benutzern Ihrer App wird wahrscheinlich dieser Namen angezeigt. Sie können ihn später ändern.
  6. Wählen Sie unter Unterstützte Kontotypen die Option Konten in allen Organisationsverzeichnissen (beliebiges Microsoft Entra-Verzeichnis: mehrere Mandanten) und persönliche Microsoft-Konten (z. B. Skype, Xbox) aus.
  7. Wählen Sie Registrieren aus.
  8. Wählen Sie unter Verwalten die Optionen Authentifizierung>Plattform hinzufügen aus.
  9. Wählen Sie Mobilgerät- und Desktopanwendungen aus.
  10. Wählen Sie im Abschnitt Umleitungs-URIs die Option https://login.microsoftonline.com/common/oauth2/nativeclient aus.
  11. Wählen Sie Konfigurierenaus.

Hinzufügen des Codes zum Initialisieren der MSAL

In diesem Schritt erstellen Sie eine Klasse zur Handhabung der Interaktion mit MSAL (beispielsweise die Handhabung von Token).

  1. Öffnen Sie die Datei App.xaml.cs, und fügen Sie der Klasse den Verweis für MSAL hinzu:

    using Microsoft.Identity.Client;
    
  2. Aktualisieren Sie die App-Klasse wie folgt:

    public partial class App : Application
    {
        static App()
        {
            _clientApp = PublicClientApplicationBuilder.Create(ClientId)
                .WithAuthority(AzureCloudInstance.AzurePublic, Tenant)
                .WithDefaultRedirectUri()
                .Build();
        }
    
        // Below are the clientId (Application Id) of your app registration and the tenant information.
        // You have to replace:
        // - the content of ClientID with the Application Id for your app registration
        // - the content of Tenant by the information about the accounts allowed to sign-in in your application:
        //   - For Work or School account in your org, use your tenant ID, or domain
        //   - for any Work or School accounts, use `organizations`
        //   - for any Work or School accounts, or Microsoft personal account, use `common`
        //   - for Microsoft Personal account, use consumers
        private static string ClientId = "Enter_the_Application_Id_here";
    
        private static string Tenant = "common";
    
        private static IPublicClientApplication _clientApp ;
    
        public static IPublicClientApplication PublicClientApp { get { return _clientApp; } }
    }
    

Erstellen der Anwendungsbenutzeroberfläche

In diesem Abschnitt erfahren Sie, wie eine Anwendung einen geschützten Back-End-Server wie Microsoft Graph abfragen kann.

Die Datei MainWindow.xaml wird als Teil Ihrer Projektvorlage automatisch erstellt. Öffnen Sie diese Datei, und ersetzen Sie den Knoten <Grid> Ihrer Anwendung durch den folgenden Code:

<Grid>
    <StackPanel Background="Azure">
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
            <Button x:Name="CallGraphButton" Content="Call Microsoft Graph API" HorizontalAlignment="Right" Padding="5" Click="CallGraphButton_Click" Margin="5" FontFamily="Segoe Ui"/>
            <Button x:Name="SignOutButton" Content="Sign-Out" HorizontalAlignment="Right" Padding="5" Click="SignOutButton_Click" Margin="5" Visibility="Collapsed" FontFamily="Segoe Ui"/>
        </StackPanel>
        <Label Content="API Call Results" Margin="0,0,0,-5" FontFamily="Segoe Ui" />
        <TextBox x:Name="ResultText" TextWrapping="Wrap" MinHeight="120" Margin="5" FontFamily="Segoe Ui"/>
        <Label Content="Token Info" Margin="0,0,0,-5" FontFamily="Segoe Ui" />
        <TextBox x:Name="TokenInfoText" TextWrapping="Wrap" MinHeight="70" Margin="5" FontFamily="Segoe Ui"/>
    </StackPanel>
</Grid>

Verwenden der MSAL zum Abrufen eines Tokens für die Microsoft Graph-API

In diesem Abschnitt nutzen Sie die MSAL, um ein Token für die Microsoft Graph-API abzurufen.

  1. Fügen Sie in der Datei MainWindow.xaml.cs der Klasse den Verweis auf die MSAL hinzu:

    using Microsoft.Identity.Client;
    
  2. Ersetzen Sie den Code der MainWindow-Klasse durch den folgenden Code:

    public partial class MainWindow : Window
    {
        //Set the API Endpoint to Graph 'me' endpoint
        string graphAPIEndpoint = "https://graph.microsoft.com/v1.0/me";
    
        //Set the scope for API call to user.read
        string[] scopes = new string[] { "user.read" };
    
    
        public MainWindow()
        {
            InitializeComponent();
        }
    
      /// <summary>
        /// Call AcquireToken - to acquire a token requiring user to sign-in
        /// </summary>
        private async void CallGraphButton_Click(object sender, RoutedEventArgs e)
        {
            AuthenticationResult authResult = null;
            var app = App.PublicClientApp;
            ResultText.Text = string.Empty;
            TokenInfoText.Text = string.Empty;
    
            var accounts = await app.GetAccountsAsync();
            var firstAccount = accounts.FirstOrDefault();
    
            try
            {
                authResult = await app.AcquireTokenSilent(scopes, firstAccount)
                    .ExecuteAsync();
            }
            catch (MsalUiRequiredException ex)
            {
                // A MsalUiRequiredException happened on AcquireTokenSilent.
                // This indicates you need to call AcquireTokenInteractive to acquire a token
                System.Diagnostics.Debug.WriteLine($"MsalUiRequiredException: {ex.Message}");
    
                try
                {
                    authResult = await app.AcquireTokenInteractive(scopes)
                        .WithAccount(accounts.FirstOrDefault())
                        .WithPrompt(Prompt.SelectAccount)
                        .ExecuteAsync();
                }
                catch (MsalException msalex)
                {
                    ResultText.Text = $"Error Acquiring Token:{System.Environment.NewLine}{msalex}";
                }
            }
            catch (Exception ex)
            {
                ResultText.Text = $"Error Acquiring Token Silently:{System.Environment.NewLine}{ex}";
                return;
            }
    
            if (authResult != null)
            {
                ResultText.Text = await GetHttpContentWithToken(graphAPIEndpoint, authResult.AccessToken);
                DisplayBasicTokenInfo(authResult);
                this.SignOutButton.Visibility = Visibility.Visible;
            }
        }
        }
    

Weitere Informationen

Interaktives Abrufen eines Benutzertokens

Das Aufrufen der AcquireTokenInteractive-Methode führt zum Öffnen eines Fensters, in dem Benutzer zum Anmelden aufgefordert werden. Bei Anwendungen müssen sich Benutzer in der Regel interaktiv anmelden, wenn sie zum ersten Mal auf eine geschützte Ressource zugreifen müssen. Die Anmeldung kann auch erforderlich sein, wenn bei dem automatischen Vorgang zum Beziehen eines Tokens ein Fehler auftritt (beispielsweise bei einem abgelaufenen Kennwort des Benutzers).

Automatisches Abrufen eines Benutzertokens

Die AcquireTokenSilent-Methode dient zum Verwalten des Abrufens und Erneuerns von Token ohne Benutzereingriff. Nachdem AcquireTokenInteractive zum ersten Mal ausgeführt wurde, ist AcquireTokenSilent die übliche Methode zum Abrufen von Token, die für den Zugriff auf geschützte Ressourcen bei nachfolgenden Aufrufen verwendet werden. Der Grund hierfür ist, dass Aufrufe zum Anfordern oder Verlängern von Token automatisch erfolgen.

Die AcquireTokenSilent-Methode kann letztendlich einen Fehler auslösen. Gründe für den Fehler können sein, dass der Benutzer sich entweder abgemeldet oder sein Kennwort auf einem anderen Gerät geändert hat. Wenn die MSAL feststellt, dass das Problem durch Anfordern einer interaktiven Aktion gelöst werden kann, löst sie eine MsalUiRequiredException-Ausnahme aus. Ihre Anwendung kann diese Ausnahme auf zwei Arten handhaben:

  • Sie kann sofort AcquireTokenInteractive aufrufen. Dieser Aufruf führt dazu, dass der Benutzer zum Anmelden aufgefordert wird. Dieses Muster wird in Onlineanwendungen verwendet, in denen keine Offlineinhalte für Benutzer*innen verfügbar sind. Das von diesem Setup erzeugte Beispiel folgt diesem Muster, das Sie bei der ersten Ausführung des Beispiels in Aktion sehen können.

  • Da bisher noch kein Benutzer die Anwendung genutzt hat, enthält PublicClientApp.Users.FirstOrDefault() einen NULL-Wert, und es wird die Ausnahme MsalUiRequiredException ausgelöst.

  • Der Code im Beispiel behandelt die Ausnahme dann durch das Aufrufen von AcquireTokenInteractive. Dies führt dazu, dass der Benutzer zum Anmelden aufgefordert wird.

  • Stattdessen kann für Benutzer auch ein visueller Hinweis gegeben werden, dass eine interaktive Anmeldung erforderlich ist, damit diese den richtigen Zeitpunkt für die Anmeldung auswählen können. Oder die Anwendung kann später noch einmal versuchen, AcquireTokenSilent auszuführen. Dieses Muster wird häufig verwendet, wenn Benutzer*innen andere Anwendungsfunktionen ohne Unterbrechungen nutzen können, z. B. wenn Offlineinhalte in der Anwendung verfügbar sind. In diesem Fall können Benutzer entscheiden, wann sie sich anmelden, um entweder auf die geschützte Ressource zuzugreifen oder die veralteten Informationen zu aktualisieren. Alternativ dazu kann die Anwendung auch versuchen, AcquireTokenSilent erneut auszuführen, wenn das Netzwerk nach einem kurzzeitigen Ausfall wiederhergestellt wurde.

Aufrufen der Microsoft Graph-API mit dem zuvor bezogenen Token

Fügen Sie MainWindow.xaml.cs die folgende neue Methode hinzu. Die Methode dient zum Senden einer GET-Anforderung an die Graph-API mithilfe eines „Authorize“-Headers:

/// <summary>
/// Perform an HTTP GET request to a URL using an HTTP Authorization header
/// </summary>
/// <param name="url">The URL</param>
/// <param name="token">The token</param>
/// <returns>String containing the results of the GET operation</returns>
public async Task<string> GetHttpContentWithToken(string url, string token)
{
    var httpClient = new System.Net.Http.HttpClient();
    System.Net.Http.HttpResponseMessage response;
    try
    {
        var request = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, url);
        //Add the token in Authorization header
        request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
        response = await httpClient.SendAsync(request);
        var content = await response.Content.ReadAsStringAsync();
        return content;
    }
    catch (Exception ex)
    {
        return ex.ToString();
    }
}

Weitere Informationen zum Richten eines REST-Aufrufs an eine geschützte API

In dieser Beispielanwendung verwenden Sie die GetHttpContentWithToken-Methode zum Senden einer HTTP GET-Anforderung an eine geschützte Ressource, für die ein Token erforderlich ist, und zum anschließenden Zurückgeben des Inhalts an den Aufrufer. Diese Methode fügt das abgerufene Token in den HTTP-Autorisierungsheader ein. In diesem Beispiel ist die Ressource der Endpunkt me der Microsoft Graph-API, der die Profilinformationen des Benutzers anzeigt.

Hinzufügen einer Methode zum Abmelden eines Benutzers

Fügen Sie Ihrer Datei MainWindow.xaml.cs die folgende Methode hinzu, um einen Benutzer abzumelden:

/// <summary>
/// Sign out the current user
/// </summary>
private async void SignOutButton_Click(object sender, RoutedEventArgs e)
{
    var accounts = await App.PublicClientApp.GetAccountsAsync();

    if (accounts.Any())
    {
        try
        {
            await App.PublicClientApp.RemoveAsync(accounts.FirstOrDefault());
            this.ResultText.Text = "User has signed-out";
            this.CallGraphButton.Visibility = Visibility.Visible;
            this.SignOutButton.Visibility = Visibility.Collapsed;
        }
        catch (MsalException ex)
        {
            ResultText.Text = $"Error signing-out user: {ex.Message}";
        }
    }
}

Weitere Informationen zur Abmeldung von Benutzern

Die SignOutButton_Click-Methode entfernt Benutzer*innen aus dem MSAL-Benutzercache. Hierdurch wird die MSAL praktisch angewiesen, den aktuellen Benutzer/die aktuelle Benutzerin zu vergessen, sodass eine künftige Anforderung zum Abrufen eines Tokens nur dann erfolgreich ist, wenn sie interaktiv gestellt wird.

Die Anwendung in diesem Beispiel unterstützt zwar einzelne Benutzer, aber die MSAL verfügt über Unterstützung für Szenarien, bei denen mehrere Konten gleichzeitig angemeldet werden können. Ein Beispiel hierfür ist eine E-Mail-Anwendung, in der ein Benutzer mehrere Konten besitzt.

Anzeigen grundlegender Informationen zum Token

Fügen Sie Ihrer Datei MainWindow.xaml.cs die folgende Methode hinzu, um grundlegende Informationen zum Token anzuzeigen:

/// <summary>
/// Display basic information contained in the token
/// </summary>
private void DisplayBasicTokenInfo(AuthenticationResult authResult)
{
    TokenInfoText.Text = "";
    if (authResult != null)
    {
        TokenInfoText.Text += $"Username: {authResult.Account.Username}" + Environment.NewLine;
        TokenInfoText.Text += $"Token Expires: {authResult.ExpiresOn.ToLocalTime()}" + Environment.NewLine;
    }
}

Weitere Informationen

Zusätzlich zu dem Zugriffstoken, das nach der Anmeldung des Benutzers zum Aufrufen der Microsoft Graph-API verwendet wird, wird mit der MSAL auch ein ID-Token bezogen. Dieses Token enthält eine kleine Teilmenge von Informationen zu den Benutzer*innen. Die DisplayBasicTokenInfo-Methode zeigt die grundlegenden Informationen an, die im Token enthalten sind. Dies sind beispielsweise der Anzeigename und die ID des Benutzers sowie das Ablaufdatum des Tokens und die Zeichenfolge, die das Zugriffstoken selbst darstellt. Wenn Sie mehrmals auf die Schaltfläche Microsoft Graph-API klicken, sehen Sie, dass dasselbe Token für nachfolgende Anforderungen wiederverwendet wurde. Sie können auch feststellen, dass das Ablaufdatum verlängert wurde, wenn die MSAL entscheidet, dass es an der Zeit ist, das Token zu verlängern.

Testen Ihres Codes

Drücken Sie F5, um das Projekt in Visual Studio auszuführen. Ihre Anwendung MainWindow wird wie im Folgenden dargestellt angezeigt:

Test your application.

Wenn Sie die Anwendung zum ersten Mal ausführen und auf die Schaltfläche Microsoft Graph-API aufrufen klicken, werden Sie zur Anmeldung aufgefordert. Verwenden Sie zum Testen ein Microsoft Entra-Konto (Geschäfts-, Schul- oder Unikonto) oder ein Microsoft-Konto (live.com, outlook.com).

Sign in to the application.

Bei der ersten Anmeldung bei Ihrer Anwendung werden Sie zudem aufgefordert, Ihre Zustimmung zu geben, dass die Anwendung auf Ihr Profil zugreifen und Sie anmelden darf, wie hier gezeigt:

Provide your consent for application access.

Anzeigen von Anwendungsergebnissen

Nachdem Sie sich angemeldet haben, sollten Sie die Benutzerprofilinformationen sehen, die vom Aufruf der Microsoft Graph-API zurückgegeben werden. Die Ergebnisse werden im Feld Ergebnisse des API-Aufrufs angezeigt. Grundlegende Informationen über das Token, das durch den Aufruf von AcquireTokenInteractive oder AcquireTokenSilent abgerufen wurde, sollten im Feld Tokeninformationen angezeigt werden. Die Ergebnisse umfassen die folgenden Eigenschaften:

Eigenschaft Format BESCHREIBUNG
Benutzername user@domain.com Der zur Identifizierung des Benutzers verwendete Benutzername
Ablaufdatum des Tokens Datetime Uhrzeit, zu der das Token abläuft. MSAL verlängert die Ablauffrist, indem das Token bei Bedarf verlängert wird.

Weitere Informationen zu Bereichen und delegierten Berechtigungen

Die Microsoft Graph-API benötigt den Bereich user.read, um das Benutzerprofil zu lesen. Dieser Bereich wird standardmäßig jeder Anwendung automatisch hinzugefügt, die im Anwendungsregistrierungsportal registriert wird. Andere Microsoft Graph-APIs sowie benutzerdefinierte APIs für Ihren Back-End-Server erfordern unter Umständen zusätzliche Bereiche. Die Microsoft Graph-API benötigt den Bereich Calendars.Read, um die Kalender des Benutzers aufzuführen.

Um auf die Kalender des Benutzers im Kontext einer Anwendung zugreifen zu können, müssen Sie den Informationen für die Anwendungsregistrierung die delegierte Berechtigung Calendars.Read hinzufügen. Fügen Sie dann dem Aufruf von acquireTokenSilent den Bereich Calendars.Read hinzu.

Hinweis

Wenn Sie die Anzahl der Bereiche erhöhen, werden Benutzer ggf. zu weiteren Genehmigungen aufgefordert.

Hilfe und Support

Wenn Sie Hilfe benötigen, ein Problem melden möchten oder sich über Ihre Supportoptionen informieren möchten, finden Sie weitere Informationen unter Hilfe und Support für Entwickler.

Nächste Schritte

Erfahren Sie in unserer mehrteiligen Szenarioreihe mehr über das Entwickeln von Desktop-Apps, die geschützte Web-APIs abrufen: