Tutorial: Memasukkan pengguna dan memanggil Microsoft Graph di aplikasi desktop Windows Presentation Foundation (WPF)

Dalam tutorial ini, Anda akan membuat aplikasi Windows Desktop .NET (XAML) asli yang memasukkan pengguna dan mendapatkan token akses untuk memanggil Microsoft Graph API.

Setelah menyelesaikan panduan, aplikasi Anda akan dapat memanggil API yang dilindungi yang menggunakan akun pribadi (termasuk outlook.com, live.com, dan lainnya). Aplikasi ini juga akan menggunakan akun kerja dan sekolah dari perusahaan atau organisasi mana pun yang menggunakan ID Microsoft Entra.

Dalam tutorial ini:

  • Membuat proyek Windows Presentation Foundation (WPF) di Visual Studio
  • Instal Pustaka Autentikasi Microsoft (MSAL) untuk .NET
  • Mendaftarkan aplikasi
  • Menambahkan kode untuk mendukung upaya masuk dan keluar pengguna
  • Menambahkan kode untuk memanggil Microsoft Graph API
  • Menguji aplikasi

Prasyarat

Cara kerja aplikasi contoh yang dihasilkan oleh panduan ini

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

Aplikasi sampel yang Anda buat dengan panduan ini memungkinkan aplikasi Windows Desktop yang meminta Api Microsoft Graph atau API web yang menerima token dari titik akhir platform identitas Microsoft. Untuk skenario ini, Anda menambahkan token ke permintaan HTTP melalui header Otorisasi. Pustaka Autentikasi Microsoft (MSAL) menangani akuisisi dan perpanjangan token.

Menangani akuisisi token untuk mengakses API web yang dilindungi

Setelah pengguna diautentikasi, aplikasi contoh menerima token yang dapat Anda gunakan untuk meminta Microsoft Graph API atau API web yang diamankan oleh platform identitas Microsoft.

API seperti Microsoft Graph memerlukan token untuk mengizinkan akses ke sumber daya tertentu. Misalnya, token diperlukan untuk membaca profil pengguna, mengakses kalender pengguna, atau mengirim email. Aplikasi Anda dapat meminta token akses dengan menggunakan MSAL untuk mengakses sumber daya ini dengan menentukan cakupan API. Token akses ini kemudian ditambahkan ke header Otorisasi HTTP untuk setiap panggilan yang dilakukan terhadap sumber daya yang dilindungi.

MSAL mengelola token akses penembolokan dan refresh untuk Anda, sehingga aplikasi Anda tidak perlu melakukannya.

Paket NuGet

Panduan ini menggunakan paket NuGet berikut:

Pustaka Deskripsi
Microsoft.Identity.Client Pustaka Autentikasi Microsoft (MSAL.NET)

Menyiapkan proyek Anda

Di bagian ini Anda akan membuat proyek baru untuk menunjukkan cara mengintegrasikan aplikasi Windows Desktop .NET (XAML) dengan Masuk dengan Microsoft sehingga aplikasi dapat mengkueri API web yang memerlukan token.

Aplikasi yang akan Anda buat menampilkan tombol yang akan memanggil Microsoft Graph API, area untuk menampilkan hasilnya, dan tombol keluar.

Catatan

Lebih suka mengunduh proyek Visual Studio sampel ini sebagai gantinya? Unduh proyek, dan lewati ke Langkah Konfigurasi untuk mengonfigurasi sampel kode sebelum Anda menjalankannya.

Buat aplikasinya dapat dengan langkah-langkah berikut:

  1. Membuka Visual Studio
  2. Di jendela mulai, pilih Buat proyek baru.
  3. Di menu dropdown Semua bahasa, pilih C#.
  4. Cari dan pilih templat Aplikasi WPF (.NET Framework), lalu pilih Berikutnya.
  5. Dalam kotak Nama proyek, masukkan nama seperti Win-App-calling-MsGraph.
  6. Pilih Lokasi untuk proyek atau terima opsi default.
  7. Di Kerangka Kerja, pilih .NET Framework 4.8.
  8. Pilih Buat.

Menambahkan MSAL ke proyek Anda

  1. Dalam Visual Studio, pilih Alat>NuGet Package Manager>Package Manager Console.

  2. Di jendela Konsol Manajer Paket, tempelkan perintah Azure PowerShell berikut ini:

    Install-Package Microsoft.Identity.Client -Pre
    

Mendaftarkan aplikasi Anda

Tip

Langkah-langkah dalam artikel ini mungkin sedikit berbeda berdasarkan portal tempat Anda memulai.

Untuk mendaftar dan mengonfigurasi aplikasi Anda, ikuti langkah-langkah berikut:

  1. Masuk ke pusat admin Microsoft Entra setidaknya sebagai Pengembang Aplikasi.
  2. Jika Anda memiliki akses ke beberapa penyewa, gunakan ikon Pengaturan di menu atas untuk beralih ke penyewa tempat Anda ingin mendaftarkan aplikasi dari menu Direktori + langganan.
  3. Telusuri Aplikasi >Identitas>Pendaftaran aplikasi.
  4. Pilih Pendaftaran baru.
  5. Masukkan Nama untuk aplikasi Anda, contohnya Win-App-calling-MsGraph. Pengguna aplikasi mungkin melihat nama ini, dan Anda dapat mengubahnya nanti.
  6. Di bagian Jenis akun yang didukung, pilih Akun di direktori organisasi apa pun (Direktori Microsoft Entra apa pun - Multipenyewa) dan akun Microsoft pribadi (misalnya Skype, Xbox).
  7. Pilih Daftarkan.
  8. Di bagian Kelola, pilih Autentikasi>Tambahkan platform.
  9. Pilih Aplikasi seluler dan desktop.
  10. Di bagian URI Pengalihan, pilih https://login.microsoftonline.com/common/oauth2/nativeclient.
  11. Pilih Konfigurasikan.

Menambahkan kode untuk menginisialisasi MSAL

Dalam langkah ini, Anda membuat kelas untuk menangani interaksi dengan MSAL, seperti penanganan token.

  1. Buka file App.xaml.cs, lalu tambahkan referensi untuk MSAL ke kelas:

    using Microsoft.Identity.Client;
    
  2. Perbarui kelas aplikasi ke hal berikut ini:

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

Buat antarmuka pengguna aplikasi

Bagian ini menampilkan bagaimana aplikasi bisa mengkueri server back-end yang dilindungi seperti Microsoft Graph.

File MainWindow.xaml secara otomatis dibuat sebagai bagian dari templat proyek Anda. Buka file ini, lalu ganti simpul <Kisi> aplikasi Anda dengan kode berikut:

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

Menggunakan MSAL untuk mendapatkan token untuk Microsoft Graph API

Di bagian ini, Anda menggunakan MSAL untuk mendapatkan token untuk Microsoft Graph API.

  1. Dalam file MainWindow.xaml.cs, tambahkan referensi untuk MSAL ke kelas:

    using Microsoft.Identity.Client;
    
  2. MainWindow Ganti kode kelas dengan kode berikut:

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

Informasi selengkapnya

Mendapatkan token pengguna secara interaktif

Memanggil metode AcquireTokenInteractive akan menampilkan jendela yang meminta pengguna untuk masuk. Aplikasi biasanya mengharuskan pengguna untuk masuk secara interaktif saat pertama kali mereka perlu mengakses sumber daya yang dilindungi. Mereka mungkin juga perlu masuk ketika operasi senyap untuk memperoleh token gagal (misalnya, ketika kata sandi pengguna kedaluwarsa).

Mendapatkan token pengguna secara diam-diam

Metode AcquireTokenSilent ini menangani akuisisi dan perpanjangan token tanpa interaksi pengguna. Setelah AcquireTokenInteractive dijalankan untuk pertama kalinya, AcquireTokenSilent adalah metode yang biasa digunakan untuk mendapatkan token yang mengakses sumber daya yang dilindungi untuk panggilan berikutnya, karena panggilan untuk meminta atau memperbarui token dilakukan secara diam-diam.

Akhirnya, AcquireTokenSilent metode mungkin gagal. Alasan kegagalan mungkin karena pengguna telah keluar atau mengubah kata sandi mereka di perangkat lain. Ketika mendeteksi bahwa masalah dapat diselesaikan dengan memerlukan tindakan interaktif, MSAL mengaktifkan pengecualian MsalUiRequiredException. Aplikasi Anda dapat menangani pengecualian ini dengan dua cara:

  • Hal ini dapat segera melakukan panggilan terhadap AcquireTokenInteractive. Panggilan ini mengakibatkan permintaan kepada pengguna untuk masuk. Pola ini digunakan dalam aplikasi online di mana tidak ada konten offline yang tersedia untuk pengguna. Sampel yang dihasilkan oleh penyiapan ini mengikuti pola ini, yang dapat dilihat dalam tindakan saat pertama kali Anda menjalankan sampel.

  • Karena tidak ada pengguna yang menggunakan aplikasi, PublicClientApp.Users.FirstOrDefault() berisi nilai null, dan pengecualian MsalUiRequiredException diaktifkan.

  • Kode dalam sampel kemudian menangani pengecualian dengan memanggil AcquireTokenInteractive, sehingga mengakibatkan meminta pengguna untuk masuk.

  • Ini malah dapat menyajikan indikasi visual kepada pengguna bahwa masuk interaktif diperlukan, sehingga mereka dapat memilih waktu yang tepat untuk masuk. Atau aplikasi dapat mencoba lagi AcquireTokenSilent nanti. Pola ini sering digunakan ketika pengguna dapat menggunakan fungsionalitas aplikasi lain tanpa gangguan. Misalnya, ketika konten offline tersedia di aplikasi. Dalam hal ini, pengguna dapat memutuskan kapan mereka ingin masuk untuk mengakses sumber daya yang dilindungi atau me-refresh informasi yang sudah tidak relevan. Atau, aplikasi dapat memutuskan untuk mencoba AcquireTokenSilent kembali ketika jaringan dipulihkan setelah sementara tidak tersedia.

Menghubungi Microsoft Graph API dengan menggunakan token yang baru saja Anda peroleh

Tambahkan metode baru berikut ke MainWindow.xaml.cs. Metode ini digunakan untuk membuat permintaan GET terhadap Graph API dengan menggunakan header Otorisasi:

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

Informasi selengkapnya tentang cara melakukan panggilan REST terhadap API yang dilindungi

Dalam aplikasi contoh ini, Anda menggunakan metode GetHttpContentWithToken untuk membuat permintaan GET HTTP terhadap sumber daya yang dilindungi yang memerlukan token dan kemudian mengembalikan konten ke pemanggil. Metode ini akan menambahkan token yang diperoleh di header Otorisasi HTTP. Untuk sampel ini, sumber daya adalah titik akhir saya, Microsoft Graph API yang menampilkan informasi profil pengguna.

Menambahkan metode untuk keluar dari pengguna

Untuk mengeluarkan pengguna, tambahkan metode berikut ke file MainWindow.xaml.cs Anda:

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

Informasi selengkapnya tentang upaya keluar pengguna

Metode ini SignOutButton_Click menghapus pengguna dari cache pengguna MSAL, yang secara efektif memberi tahu MSAL untuk melupakan pengguna saat ini sehingga permintaan di masa mendatang untuk memperoleh token berhasil hanya jika dibuat menjadi interaktif.

Meskipun aplikasi dalam sampel ini mendukung pengguna tunggal, MSAL mendukung skenario di mana beberapa akun dapat masuk secara bersamaan. Contohnya adalah aplikasi email di mana pengguna memiliki beberapa akun.

Menampilkan informasi token dasar

Untuk menampilkan informasi dasar tentang token, tambahkan metode berikut ke file mainWindow.xaml.cs Anda:

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

Informasi selengkapnya

Selain token akses yang digunakan untuk memanggil Microsoft Graph API, setelah pengguna masuk, MSAL juga mendapatkan token ID. Token ini berisi subset kecil informasi yang berkaitan dengan pengguna. DisplayBasicTokenInfoMetode ini menampilkan informasi dasar yang ada dalam token. Misalnya, menampilkan nama tampilan dan ID pengguna, serta kedaluwarsa token dan string yang mewakili token akses itu sendiri. Anda dapat memilih tombol Panggil Microsoft Graph API beberapa kali dan melihat bahwa token yang sama digunakan kembali untuk permintaan berikutnya. Anda juga dapat melihat tanggal kedaluwarsa diperpanjang ketika MSAL memutuskan saatnya untuk memperbarui token.

Menguji kode

Untuk menjalankan proyek Anda, di Visual Studio, pilih F5. Aplikasi Anda MainWindow ditampilkan, seperti yang diperlihatkan di sini:

Test your application.

Saat pertama kali Anda menjalankan aplikasi dan memilih tombol Panggil Microsoft Graph API, Anda akan diminta untuk masuk. Gunakan akun Microsoft Entra (akun kerja atau sekolah) atau akun Microsoft (live.com, outlook.com) untuk mengujinya.

Sign in to the application.

Saat pertama kali masuk ke aplikasi, Anda juga diminta untuk memberikan persetujuan untuk mengizinkan aplikasi mengakses profil Anda dan memasukkan Anda, seperti yang diperlihatkan di sini:

Provide your consent for application access.

Melihat hasil aplikasi

Setelah masuk, Anda akan melihat informasi profil pengguna yang dikembalikan oleh panggilan ke Microsoft Graph API. Hasil ditampilkan dalam kotak Hasil Panggilan API. Informasi dasar tentang token yang diperoleh melalui panggilan ke AcquireTokenInteractive atau AcquireTokenSilent harus terlihat di kotak Info Token. Hasilnya berisi properti berikut:

Properti Format Deskripsi
Username user@domain.com Nama pengguna yang digunakan untuk mengidentifikasi pengguna.
Masa Berakhir Token DateTime Kapan token kedaluwarsa. MSAL memperpanjang tanggal kedaluwarsa dengan memperbarui token seperlunya.

Informasi selengkapnya tentang cakupan dan izin yang didelegasikan

Microsoft Graph API memerlukan cakupan user.read untuk membaca profil pengguna. Cakupan ini secara otomatis ditambahkan secara default di setiap aplikasi yang terdaftar di Portal Pendaftaran Aplikasi. API lain untuk Microsoft Graph, serta API kustom untuk server ujung belakang, mungkin mewajibkan cakupan tambahan. Microsoft Graph API memerlukan cakupan Calendars.Read untuk mencantumkan kalender pengguna.

Untuk mengakses kalender pengguna dalam konteks aplikasi, tambahkan izin delegasi Calendars.Read ke informasi pendaftaran aplikasi. Lalu, tambahkan cakupan Calendars.Read panggilan acquireTokenSilent.

Catatan

Pengguna mungkin diminta untuk memberikan persetujuan tambahan saat Anda meningkatkan jumlah cakupan.

Bantuan dan dukungan

Jika Anda memerlukan bantuan, ingin melaporkan masalah, atau ingin mempelajari opsi dukungan, lihat Bantuan dan dukungan bagi pengembang.

Langkah berikutnya

Pelajari selengkapnya tentang membuat aplikasi desktop yang memanggil API web yang dilindungi dalam seri skenario multi-bagian kami: