Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Berlaku untuk: Penyewa tenaga kerja
Penyewa eksternal (lihat selengkapnya)
Tutorial ini menunjukkan cara membuat aplikasi desktop Windows Presentation Form (WPF) dan menyiapkannya untuk autentikasi menggunakan pusat admin Microsoft Entra.
Di tutorial ini, Anda akan:
- Konfigurasikan aplikasi desktop WPF untuk menggunakan rincian pendaftaran aplikasi.
- Buat aplikasi desktop yang mendaftarkan pengguna dan memperoleh token atas nama pengguna.
Prasyarat
- Daftarkan aplikasi baru di pusat admin Microsoft Entra, dikonfigurasi untuk Akun di direktori organisasi dan akun Microsoft pribadi apa pun. Lihat Mendaftarkan aplikasi untuk detail selengkapnya. Rekam nilai berikut dari halaman Gambaran Umum aplikasi untuk digunakan nanti:
- ID Aplikasi (klien)
- ID Direktori (Penyewa)
- Nama domain direktori (penyewa) (misalnya, contoso.onmicrosoft.com atau contoso.com).
- Tambahkan URI pengalihan berikut menggunakan konfigurasi platform Aplikasi seluler dan desktop . Lihat Cara menambahkan URI pengalihan di aplikasi Anda untuk detail selengkapnya.
-
URI Pengalihan:
https://login.microsoftonline.com/common/oauth2/nativeclient
-
URI Pengalihan:
- Kaitkan aplikasi Anda dengan alur pengguna di pusat admin Microsoft Entra. Alur pengguna ini dapat digunakan di beberapa aplikasi. Untuk informasi selengkapnya, lihat Membuat alur pengguna pendaftaran layanan mandiri untuk aplikasi di penyewa eksternal dan Menambahkan aplikasi Anda ke alur pengguna.
- .NET 7.0 SDK atau yang lebih baru.
- Meskipun setiap lingkungan pengembangan terintegrasi (IDE) yang mendukung aplikasi React dapat digunakan, tutorial ini menggunakan Visual Studio Code.
Membuat aplikasi desktop WPF
Buka terminal Anda dan navigasikan ke folder tempat Anda ingin proyek Anda tinggal.
Menginisialisasi aplikasi desktop WPF dan menavigasi ke folder akarnya.
dotnet new wpf --language "C#" --name sign-in-dotnet-wpf cd sign-in-dotnet-wpf
Memasang paket
Instal penyedia konfigurasi yang membantu aplikasi kami membaca data konfigurasi dari pasangan kunci-nilai dalam file pengaturan aplikasi kami. Abstraksi konfigurasi ini memberikan kemampuan untuk mengikat nilai konfigurasi ke instans objek .NET.
dotnet add package Microsoft.Extensions.Configuration
dotnet add package Microsoft.Extensions.Configuration.Json
dotnet add package Microsoft.Extensions.Configuration.Binder
Instal Microsoft Authentication Library (MSAL) yang berisi semua komponen utama yang Anda butuhkan untuk memperoleh token. Anda juga menginstal perpustakaan broker MSAL yang menangani interaksi dengan broker autentikasi desktop.
dotnet add package Microsoft.Identity.Client
dotnet add package Microsoft.Identity.Client.Broker
Membuat file appsettings.json dan menambahkan konfigurasi pendaftaran
Buat file appsettings.json di folder akar aplikasi.
Tambahkan detail pendaftaran aplikasi ke file appsettings.json .
{ "AzureAd": { "Authority": "https://<Enter_the_Tenant_Subdomain_Here>.ciamlogin.com/", "ClientId": "<Enter_the_Application_Id_Here>" } }
- Ganti
Enter_the_Tenant_Subdomain_Here
dengan subdomain Direktori (penyewa). - Ganti
Enter_the_Application_Id_Here
dengan ID Aplikasi (klien) aplikasi yang Anda daftarkan sebelumnya.
- Ganti
Setelah membuat file pengaturan aplikasi, kami akan membuat file lain yang disebut AzureAdConfig.cs yang akan membantu Anda membaca konfigurasi dari file pengaturan aplikasi. Buat file AzureAdConfig.cs di folder akar aplikasi.
Dalam file AzureAdConfig.js, tentukan getter dan setter untuk properti
ClientId
danAuthority
. Tambahkan kode berikut:namespace sign_in_dotnet_wpf { public class AzureAdConfig { public string Authority { get; set; } public string ClientId { get; set; } } }
Menggunakan domain URL kustom (Opsional)
Gunakan domain kustom untuk sepenuhnya memberi merek URL autentikasi. Dari perspektif pengguna, pengguna tetap berada di domain Anda selama proses autentikasi, daripada dialihkan ke nama domain ciamlogin.com.
Ikuti langkah-langkah ini untuk menggunakan domain kustom:
Gunakan langkah-langkah dalam Mengaktifkan domain URL kustom untuk aplikasi di penyewa eksternal untuk mengaktifkan domain URL kustom untuk penyewa eksternal Anda.
Buka file appsettings.json:
- Perbarui nilai properti
Authority
ke https://Enter_the_Custom_Domain_Here/Enter_the_Tenant_ID_Here. GantiEnter_the_Custom_Domain_Here
dengan domain URL kustom Anda danEnter_the_Tenant_ID_Here
dengan ID penyewa Anda. Jika Anda tidak memiliki ID penyewa, pelajari cara membaca rincian penyewa Anda. - Tambahkan properti
knownAuthorities
dengan nilai [Enter_the_Custom_Domain_Here].
- Perbarui nilai properti
Setelah Anda membuat perubahan pada file appsettings.json Anda, jika domain URL kustom Anda login.contoso.com, dan ID penyewa Anda aaaabbbb-0000-cc-1111-dddd22222ee, maka file Anda akan terlihat mirip dengan cuplikan berikut:
{
"AzureAd": {
"Authority": "https://login.contoso.com/aaaabbbb-0000-cccc-1111-dddd2222eeee",
"ClientId": "Enter_the_Application_Id_Here",
"KnownAuthorities": ["login.contoso.com"]
}
}
Mengubah file proyek
Navigasikan ke file sign-in-dotnet-wpf.csproj di folder akar aplikasi.
Dalam file ini, lakukan dua langkah berikut:
- Ubah file sign-in-dotnet-wpf.csproj untuk menginstruksikan aplikasi Anda menyalin file appsettings.json ke direktori output saat proyek dikompilasi. Tambahkan bagian kode berikut ke file sign-in-dotnet-wpf.csproj :
- Atur kerangka kerja target menjadi build windows10.0.19041.0 untuk membantu membaca token yang di-cache seperti yang terlihat di kelas pembantu cache token.
<Project Sdk="Microsoft.NET.Sdk"> ... <!-- Set target framework to target windows10.0.19041.0 build --> <PropertyGroup> <OutputType>WinExe</OutputType> <TargetFramework>net7.0-windows10.0.19041.0</TargetFramework> <!-- target framework --> <RootNamespace>sign_in_dotnet_wpf</RootNamespace> <Nullable>enable</Nullable> <UseWPF>true</UseWPF> </PropertyGroup> <!-- Copy appsettings.json file to output folder. --> <ItemGroup> <None Remove="appsettings.json" /> </ItemGroup> <ItemGroup> <EmbeddedResource Include="appsettings.json"> <CopyToOutputDirectory>Always</CopyToOutputDirectory> </EmbeddedResource> </ItemGroup> </Project>
Membuat kelas pembantu cache token
Buat kelas pembantu cache token yang menginisialisasi cache token. Aplikasi mencoba membaca token dari cache sebelum mencoba memperoleh token baru. Jika token tidak ditemukan di cache, aplikasi memperoleh token baru. Setelah keluar, cache dihapus dari semua akun dan semua token akses yang sesuai.
Buat file TokenCacheHelper.cs di folder akar aplikasi.
Buka file TokenCacheHelper.cs. Tambahkan paket dan namespace ke file. Dalam langkah-langkah berikut, Anda mengisi file ini dengan logika kode dengan menambahkan logika yang relevan ke
TokenCacheHelper
kelas .using System.IO; using System.Security.Cryptography; using Microsoft.Identity.Client; namespace sign_in_dotnet_wpf { static class TokenCacheHelper{} }
Tambahkan konstruktor ke
TokenCacheHelper
kelas yang menentukan jalur file cache. Untuk aplikasi desktop yang dipaketkan (paket MSIX, juga disebut Desktop Bridge), folder perakitan yang dijalankan bersifat baca-saja. Dalam hal ini kita perlu menggunakanWindows.Storage.ApplicationData.Current.LocalCacheFolder.Path + "\msalcache.bin"
yang merupakan folder baca/tulis per aplikasi untuk aplikasi yang dipaketkan.namespace sign_in_dotnet_wpf { static class TokenCacheHelper { static TokenCacheHelper() { try { CacheFilePath = Path.Combine(Windows.Storage.ApplicationData.Current.LocalCacheFolder.Path, ".msalcache.bin3"); } catch (System.InvalidOperationException) { CacheFilePath = System.Reflection.Assembly.GetExecutingAssembly().Location + ".msalcache.bin3"; } } public static string CacheFilePath { get; private set; } private static readonly object FileLock = new object(); } }
Tambahkan kode untuk menangani serialisasi cache token. Antarmuka
ITokenCache
mengimplementasikan akses publik ke operasi cache.ITokenCache
antarmuka berisi metode untuk berlangganan peristiwa serialisasi cache, sementara antarmukaITokenCacheSerializer
mengekspos metode yang perlu Anda gunakan dalam peristiwa serialisasi cache, untuk membuat serialisasi/deserialisasi cache.TokenCacheNotificationArgs
berisi parameter yang digunakan dalam panggilanMicrosoft.Identity.Client
(MSAL) untuk mengakses cache.ITokenCacheSerializer
antarmuka dapat digunakan diTokenCacheNotificationArgs
panggilan balik.Tambahkan kode berikut ke kelas
TokenCacheHelper
:static class TokenCacheHelper { static TokenCacheHelper() {...} public static string CacheFilePath { get; private set; } private static readonly object FileLock = new object(); public static void BeforeAccessNotification(TokenCacheNotificationArgs args) { lock (FileLock) { args.TokenCache.DeserializeMsalV3(File.Exists(CacheFilePath) ? ProtectedData.Unprotect(File.ReadAllBytes(CacheFilePath), null, DataProtectionScope.CurrentUser) : null); } } public static void AfterAccessNotification(TokenCacheNotificationArgs args) { if (args.HasStateChanged) { lock (FileLock) { File.WriteAllBytes(CacheFilePath, ProtectedData.Protect(args.TokenCache.SerializeMsalV3(), null, DataProtectionScope.CurrentUser) ); } } } } internal static void EnableSerialization(ITokenCache tokenCache) { tokenCache.SetBeforeAccess(BeforeAccessNotification); tokenCache.SetAfterAccess(AfterAccessNotification); }
Dalam metode ini
BeforeAccessNotification
, Anda membaca cache dari sistem file, dan jika cache tersebut tidak kosong, Anda mendeserialisasinya dan memuatnya. MetodeAfterAccessNotification
ini dipanggil setelahMicrosoft.Identity.Client
(MSAL) mengakses cache. Jika cache telah berubah, Anda menserialisasikannya dan mempertahankan perubahan pada cache.EnableSerialization
berisi metodeITokenCache.SetBeforeAccess()
danITokenCache.SetAfterAccess()
.-
ITokenCache.SetBeforeAccess()
mengatur wakil yang akan menerima pemberitahuan sebelum metode pustaka mengakses cache. Ini memberikan pilihan kepada delegasi untuk mendeserialisasi entri cache untuk aplikasi dan akun-akun yang ditentukan dalam tagTokenCacheNotificationArgs
. -
ITokenCache.SetAfterAccess()
mengatur delegat yang akan diberi tahu setelah fungsi pustaka mengakses cache. Ini memberikan opsi kepada delegasi untuk membuat serialisasi entri cache untuk aplikasi dan akun yang ditentukan dalamTokenCacheNotificationArgs
.
-
Membuat UI aplikasi desktop WPF
Ubah file MainWindow.xaml untuk menambahkan elemen UI untuk aplikasi.
Buka file MainWindow.xaml di folder akar aplikasi dan tambahkan bagian kode berikut dengan bagian <Grid></Grid>
kontrol.
<StackPanel Background="Azure">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button x:Name="SignInButton" Content="Sign-In" HorizontalAlignment="Right" Padding="5" Click="SignInButton_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="Authentication Result" 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>
Kode ini menambahkan elemen UI kunci. Metode dan objek yang menangani fungsionalitas elemen UI didefinisikan dalam file MainWindow.xaml.cs yang kita buat di langkah berikutnya.
- Tombol untuk masuk pengguna.
SignInButton_Click
metode dipanggil ketika pengguna memilih tombol ini. - Tombol yang mengeluarkan pengguna dari akun.
SignOutButton_Click
metode dipanggil ketika pengguna memilih tombol ini. - Kotak teks yang menampilkan detail hasil autentikasi setelah pengguna mencoba masuk. Informasi yang ditampilkan di sini dikembalikan oleh
ResultText
objek. - Kotak teks yang menampilkan detail token setelah pengguna berhasil masuk. Informasi yang ditampilkan di sini dikembalikan oleh
TokenInfoText
objek.
Menambahkan kode ke file MainWindow.xaml.cs
File MainWindow.xaml.cs berisi kode yang menyediakan logika runtime th untuk perilaku elemen UI dalam file MainWindow.xaml .
Buka file MainWindow.xaml.cs di folder akar aplikasi.
Tambahkan kode berikut ke dalam file untuk mengimpor paket, dan tentukan placeholder untuk metode yang kita buat.
using Microsoft.Identity.Client; using System; using System.Linq; using System.Windows; using System.Windows.Interop; namespace sign_in_dotnet_wpf { public partial class MainWindow : Window { string[] scopes = new string[] { }; public MainWindow() { InitializeComponent(); } private async void SignInButton_Click(object sender, RoutedEventArgs e){...} private async void SignOutButton_Click(object sender, RoutedEventArgs e){...} private void DisplayBasicTokenInfo(AuthenticationResult authResult){...} } }
Tambahkan kode berikut ke metode
SignInButton_Click
. Metode ini dipanggil ketika pengguna memilih tombol Masuk .private async void SignInButton_Click(object sender, RoutedEventArgs e) { AuthenticationResult authResult = null; var app = App.PublicClientApp; ResultText.Text = string.Empty; TokenInfoText.Text = string.Empty; IAccount firstAccount; var accounts = await app.GetAccountsAsync(); firstAccount = accounts.FirstOrDefault(); try { authResult = await app.AcquireTokenSilent(scopes, firstAccount) .ExecuteAsync(); } catch (MsalUiRequiredException ex) { try { authResult = await app.AcquireTokenInteractive(scopes) .WithAccount(firstAccount) .WithParentActivityOrWindow(new WindowInteropHelper(this).Handle) .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 = "Sign in was successful."; DisplayBasicTokenInfo(authResult); this.SignInButton.Visibility = Visibility.Collapsed; this.SignOutButton.Visibility = Visibility.Visible; } } }
GetAccountsAsync()
mengembalikan semua akun yang tersedia di cache token pengguna untuk aplikasi. AntarmukaIAccount
mewakili informasi tentang satu akun.Untuk memperoleh token, aplikasi mencoba memperoleh token secara diam-diam
AcquireTokenSilent
menggunakan metode untuk memverifikasi apakah token yang dapat diterima ada di cache. MetodeAcquireTokenSilent
mungkin gagal, misalnya, karena pengguna keluar. Ketika MSAL mendeteksi bahwa masalah dapat diselesaikan dengan memerlukan tindakan interaktif, MSAL melemparkanMsalUiRequiredException
pengecualian. Pengecualian ini menyebabkan aplikasi memperoleh token 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 mengautentikasi. Mereka mungkin juga perlu masuk saat proses tanpa suara untuk memperoleh token. SetelahAcquireTokenInteractive
dijalankan untuk pertama kalinya,AcquireTokenSilent
menjadi metode yang biasa digunakan untuk mendapatkan tokenTambahkan kode berikut ke metode
SignOutButton_Click
. Metode ini dipanggil ketika pengguna memilih tombol Keluar .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.TokenInfoText.Text = string.Empty; this.SignInButton.Visibility = Visibility.Visible; this.SignOutButton.Visibility = Visibility.Collapsed; } catch (MsalException ex) { ResultText.Text = $"Error signing-out user: {ex.Message}"; } } }
Metode ini
SignOutButton_Click
menghapus cache semua akun dan semua token akses yang sesuai. Lain kali pengguna mencoba masuk, mereka harus melakukannya secara interaktif.Tambahkan kode berikut ke metode
DisplayBasicTokenInfo
. Metode ini menampilkan informasi dasar tentang token.private void DisplayBasicTokenInfo(AuthenticationResult authResult) { TokenInfoText.Text = ""; if (authResult != null) { TokenInfoText.Text += $"Username: {authResult.Account.Username}" + Environment.NewLine; TokenInfoText.Text += $"{authResult.Account.HomeAccountId}" + Environment.NewLine; } }
Menambahkan kode ke file App.xaml.cs
App.xaml adalah tempat Anda mendeklarasikan sumber daya yang digunakan di seluruh aplikasi. Ini adalah titik masuk untuk aplikasi Anda. App.xaml.cs adalah kode di belakang file untuk App.xaml. App.xaml.cs juga menentukan jendela mulai untuk aplikasi Anda.
Buka file App.xaml.cs di folder akar aplikasi, lalu tambahkan kode berikut ke dalamnya.
using System.Windows;
using System.Reflection;
using Microsoft.Identity.Client;
using Microsoft.Identity.Client.Broker;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.Json;
namespace sign_in_dotnet_wpf
{
public partial class App : Application
{
static App()
{
CreateApplication();
}
public static void CreateApplication()
{
var assembly = Assembly.GetExecutingAssembly();
using var stream = assembly.GetManifestResourceStream("sign_in_dotnet_wpf.appsettings.json");
AppConfiguration = new ConfigurationBuilder()
.AddJsonStream(stream)
.Build();
AzureAdConfig azureADConfig = AppConfiguration.GetSection("AzureAd").Get<AzureAdConfig>();
var builder = PublicClientApplicationBuilder.Create(azureADConfig.ClientId)
.WithAuthority(azureADConfig.Authority)
.WithDefaultRedirectUri();
_clientApp = builder.Build();
TokenCacheHelper.EnableSerialization(_clientApp.UserTokenCache);
}
private static IPublicClientApplication _clientApp;
private static IConfiguration AppConfiguration;
public static IPublicClientApplication PublicClientApp { get { return _clientApp; } }
}
}
Dalam langkah ini, Anda memuat file appsettings.json . Penyusun konfigurasi membantu Anda membaca konfigurasi aplikasi yang ditentukan dalam file appsettings.json . Anda juga menentukan aplikasi WPF sebagai aplikasi klien publik karena ini adalah aplikasi desktop. Metode ini TokenCacheHelper.EnableSerialization
memungkinkan serialisasi cache token.
Menjalankan aplikasi
Jalankan aplikasi Anda dan masuk untuk menguji aplikasi
Di terminal Anda, navigasikan ke folder akar aplikasi WPF Anda dan jalankan aplikasi dengan menjalankan perintah
dotnet run
di terminal Anda.Setelah meluncurkan sampel, Anda akan melihat jendela dengan tombol Masuk . Pilih tombol Masuk .
Pada halaman masuk, masukkan alamat email akun Anda. Jika Anda tidak memiliki akun, pilih Tidak ada akun? Buat, yang memulai alur pendaftaran. Ikuti alur ini untuk membuat akun baru dan masuk.
Setelah masuk, Anda akan melihat layar yang menampilkan keberhasilan masuk dan informasi dasar tentang akun pengguna Anda yang disimpan dalam token yang diambil. Informasi dasar ditampilkan di bagian Info Token layar login