Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Platí pro:
Externí tenanti (další informace)
Tento kurz ukazuje, jak vytvořit desktopovou aplikaci WPF (Windows Presentation Form) a připravit ji na ověřování pomocí Centra pro správu Microsoft Entra.
V tomto kurzu se naučíte:
- Nakonfigurujte desktopovou aplikaci WPF tak, aby používala podrobnosti o registraci aplikace.
- Vytvořte desktopovou aplikaci, která přihlásí uživatele a získá token jménem uživatele.
Požadavky
- Zaregistrujte novou aplikaci v Centru pro správu Microsoft Entra nakonfigurované pro účty v libovolném organizačním adresáři a osobních účtech Microsoft. Další podrobnosti najdete v tématu Registrace aplikace . Na stránce Přehled aplikace si poznamenejte následující hodnoty pro pozdější použití:
- ID aplikace (klienta)
- ID adresáře (klienta)
- Název domény adresáře (tenanta) (například contoso.onmicrosoft.com nebo contoso.com).
- Přidejte následující URI přesměrování pomocí konfigurace platformy Mobilní a desktopové aplikace. Další podrobnosti najdete v tématu Jak přidat URI pro přesměrování ve vaší aplikaci.
-
Přesměrovací URI:
https://login.microsoftonline.com/common/oauth2/nativeclient
-
Přesměrovací URI:
- Přidružte aplikaci k toku uživatele v Centru pro správu Microsoft Entra. Tento tok uživatele je možné použít v různých aplikacích. Pro další informace si přečtěte Vytvoření samoobslužných toků registrace uživatelů pro aplikace v externích tenantech a Přidání vaší aplikace do uživatelského toku.
- .NET 7.0 SDK nebo novější.
- I když je možné použít jakékoli integrované vývojové prostředí (IDE), které podporuje aplikace React, tento kurz používá Visual Studio Code.
Vytvoření desktopové aplikace WPF
Otevřete terminál a přejděte do složky, ve které má projekt žít.
Inicializuje desktopovou aplikaci WPF a přejde do její kořenové složky.
dotnet new wpf --language "C#" --name sign-in-dotnet-wpf cd sign-in-dotnet-wpf
Instalace balíčků
Nainstalujte zprostředkovatele konfigurace, kteří aplikaci pomáhají číst konfigurační data z párů klíč-hodnota v souboru nastavení aplikace. Tyto abstrakce konfigurace poskytují možnost svázat konfigurační hodnoty s instancemi objektů .NET.
dotnet add package Microsoft.Extensions.Configuration
dotnet add package Microsoft.Extensions.Configuration.Json
dotnet add package Microsoft.Extensions.Configuration.Binder
Nainstalujte knihovnu MSAL (Microsoft Authentication Library), která obsahuje všechny klíčové komponenty, které potřebujete k získání tokenu. Také nainstalujete knihovnu zprostředkovatele MSAL, která zpracovává interakce se zprostředkovateli ověřování na ploše.
dotnet add package Microsoft.Identity.Client
dotnet add package Microsoft.Identity.Client.Broker
Vytvoření souboru appsettings.json a přidání konfigurací registrace
Vytvořte soubor appsettings.json v kořenové složce aplikace.
Do souboru appsettings.json přidejte podrobnosti o registraci aplikace.
{ "AzureAd": { "Authority": "https://<Enter_the_Tenant_Subdomain_Here>.ciamlogin.com/", "ClientId": "<Enter_the_Application_Id_Here>" } }- Nahraďte
Enter_the_Tenant_Subdomain_Heresubdoménou adresáře (tenanta). - Nahraďte
Enter_the_Application_Id_HereIDem aplikace (klienta), kterou jste zaregistrovali dříve.
- Nahraďte
Po vytvoření souboru nastavení aplikace vytvoříme další soubor s názvem AzureAdConfig.cs , který vám pomůže číst konfigurace ze souboru nastavení aplikace. Vytvořte soubor AzureAdConfig.cs v kořenové složce aplikace.
V souboru AzureAdConfig.js definujte gettery a settery pro
ClientIdaAuthority. Přidejte následující kód:namespace sign_in_dotnet_wpf { public class AzureAdConfig { public string Authority { get; set; } public string ClientId { get; set; } } }
Použití vlastní domény URL (volitelné)
Použijte vlastní doménu pro zajištění plného brandingu URL ověřování. Z uživatelského pohledu zůstanou uživatelé ve vaší doméně během procesu ověřování, a nejsou přesměrováni na doménu ciamlogin.com.
Pokud chcete použít vlastní doménu, postupujte takto:
Pomocí kroků v Povolení vlastních domén URL pro aplikace v externích tenantech povolte pro externího tenanta vlastní doménu URL.
Otevřete soubor appsettings.json:
- Aktualizujte hodnotu vlastnosti
Authorityna https://Enter_the_Custom_Domain_Here/Enter_the_Tenant_ID_Here. NahraďteEnter_the_Custom_Domain_Herevlastní doménou URL aEnter_the_Tenant_ID_HereID tenanta. Pokud nemáte ID tenanta, zjistěte, jak získat podrobnosti o tenantovi. - Přidejte vlastnost
knownAuthoritiess hodnotou [Enter_the_Custom_Domain_Here].
- Aktualizujte hodnotu vlastnosti
Po provedení změn souboru appsettings.json , pokud je vaše vlastní doména URL login.contoso.com a ID vašeho tenanta je aaaabbbb-0000-cccc-1111-dddd2222eeeee, měl by váš soubor vypadat podobně jako následující fragment kódu:
{
"AzureAd": {
"Authority": "https://login.contoso.com/aaaabbbb-0000-cccc-1111-dddd2222eeee",
"ClientId": "Enter_the_Application_Id_Here",
"KnownAuthorities": ["login.contoso.com"]
}
}
Úprava souboru projektu
Přejděte do souboru sign-in-dotnet-wpf.csproj v kořenové složce aplikace.
V tomto souboru proveďte následující dva kroky:
- Upravte soubor sign-in-dotnet-wpf.csproj, aby aplikace při kompilaci projektu zkopírovala soubor appsettings.json do výstupního adresáře. Do souboru sign-in-dotnet-wpf.csproj přidejte následující kód:
- Nastavte cílový framework na verzi build windows10.0.19041.0, která vám pomůže při čtení tokenu z mezipaměti tokenů, jak můžete vidět v pomocné třídě pro mezipaměť 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>
Vytvoření pomocné třídy mezipaměti tokenů
Vytvořte pomocnou třídu mezipaměti tokenů, která inicializuje mezipaměť tokenů. Aplikace se pokusí načíst token z mezipaměti předtím, než se pokusí získat nový token. Pokud se token v mezipaměti nenajde, aplikace získá nový token. Po odhlášení se mezipaměť vymaže ze všech účtů a všech odpovídajících přístupových tokenů.
Vytvořte soubor TokenCacheHelper.cs v kořenové složce aplikace.
Otevřete soubor TokenCacheHelper.cs. Přidejte do souboru balíčky a obory názvů. V následujících krocích naplníte tento soubor logikou kódu přidáním příslušné logiky do
TokenCacheHelpertřídy.using System.IO; using System.Security.Cryptography; using Microsoft.Identity.Client; namespace sign_in_dotnet_wpf { static class TokenCacheHelper{} }Přidejte konstruktor do
TokenCacheHelpertřídy, která definuje cestu k souboru mezipaměti. Pro zabalené desktopové aplikace (balíčky MSIX, označované také jako desktopová propojení) je složka prováděcího sestavení určená pouze pro čtení. V takovém případě musíme použítWindows.Storage.ApplicationData.Current.LocalCacheFolder.Path + "\msalcache.bin", což je složka pro čtení a zápis pro každou aplikaci určená pro balíčkované aplikace.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(); } }Přidejte kód pro zpracování serializace mezipaměti tokenů. Rozhraní
ITokenCacheimplementuje veřejný přístup k operacím mezipaměti.ITokenCacherozhraní obsahuje metody pro přihlášení k odběru událostí serializace mezipaměti, zatímco rozhraníITokenCacheSerializerposkytuje metody, které potřebujete použít v událostech serializace mezipaměti, abyste mohli provádět serializaci/deserializaci mezipaměti.TokenCacheNotificationArgsobsahuje parametry používané volánímMicrosoft.Identity.ClientMSAL, které přistupuje k mezipaměti.ITokenCacheSerializerrozhraní je dostupné vTokenCacheNotificationArgscallbacku.Do třídy
TokenCacheHelperpřidejte následující kód: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); }BeforeAccessNotificationV metodě načtete mezipaměť ze systému souborů a pokud mezipaměť není prázdná, deserializujete ji a načtete ji. MetodaAfterAccessNotificationse volá poté, coMicrosoft.Identity.Client(MSAL) přistupuje k mezipaměti. Pokud se mezipaměť změnila, serializujete ji a zachovají se změny v mezipaměti.Systém
EnableSerializationobsahuje metodyITokenCache.SetBeforeAccess()aITokenCache.SetAfterAccess().-
ITokenCache.SetBeforeAccess()nastaví delegáta, který má být upozorněn před přístupem jakékoli metody knihovny k mezipaměti. To dává delegátu možnost deserializovat položku mezipaměti pro aplikaci a účty zadané v souboruTokenCacheNotificationArgs. -
ITokenCache.SetAfterAccess()nastaví delegáta, který bude upozorněn po každém přístupu metody knihovny k mezipaměti. To dává delegátu možnost serializovat položku mezipaměti pro aplikaci a účty zadané v souboruTokenCacheNotificationArgs.
-
Vytvoření uživatelského rozhraní desktopové aplikace WPF
Upravte soubor MainWindow.xaml a přidejte prvky uživatelského rozhraní pro aplikaci.
Otevřete soubor MainWindow.xaml v kořenové složce aplikace a přidejte následující část kódu s <Grid></Grid> částí ovládacího prvku.
<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>
Tento kód přidá klíčové prvky uživatelského rozhraní. Metody a objekty, které zpracovávají funkčnost prvků uživatelského rozhraní, jsou definovány v MainWindow.xaml.cs souboru, který vytvoříme v dalším kroku.
- Tlačítko, které uživatele přihlásí.
SignInButton_Clickmetoda je volána, když uživatel vybere toto tlačítko. - Tlačítko, které uživatele odhlásí.
SignOutButton_Clickmetoda je volána, když uživatel vybere toto tlačítko. - Textové pole, které zobrazuje podrobnosti výsledku ověření po pokusu uživatele o přihlášení. Informace zobrazené zde vrácené objektem
ResultText. - Textové pole, které zobrazí podrobnosti tokenu po úspěšném přihlášení uživatele. Informace zobrazené zde vrácené objektem
TokenInfoText.
Přidání kódu do souboru MainWindow.xaml.cs
Soubor MainWindow.xaml.cs obsahuje kód, který poskytuje logiku modulu runtime pro chování prvků uživatelského rozhraní v souboru MainWindow.xaml .
Otevřete soubor MainWindow.xaml.cs v kořenové složce aplikace.
Do souboru přidejte následující kód pro import balíčků a definujte zástupné symboly pro metody, které vytvoříme.
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){...} } }Do metody
SignInButton_Clickpřidejte následující kód. Tato metoda se volá, když uživatel vybere tlačítko Přihlásit se.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()vrátí všechny dostupné účty v mezipaměti tokenů uživatele pro aplikaci. RozhraníIAccountpředstavuje informace o jednom účtu.K získání tokenů se aplikace pokusí token získat bezobslužně pomocí
AcquireTokenSilentmetody, aby ověřila, jestli je v mezipaměti přijatelný token. MetodaAcquireTokenSilentmůže například selhat, protože se uživatel odhlásil. Když služba MSAL zjistí, že problém lze vyřešit vyžadováním interaktivní akce, vyvoláMsalUiRequiredExceptionvýjimku. Tato výjimka způsobí, že aplikace interaktivně získá token.AcquireTokenInteractiveVolání metody způsobí, že se zobrazí okno s výzvou, aby se uživatelé přihlásili. Aplikace obvykle vyžadují, aby se uživatelé přihlašovali interaktivně při prvním ověření. Také se mohou potřebovat přihlásit, pokud se použije bezobslužná operace pro získání tokenu. Po prvním spuštěníAcquireTokenInteractiveseAcquireTokenSilentstane obvyklou metodou pro získání tokenů.Do metody
SignOutButton_Clickpřidejte následující kód. Tato metoda se volá, když uživatel vybere tlačítko Odhlásit se .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}"; } } }Metoda
SignOutButton_Clickvymaže mezipaměť všech účtů a všech odpovídajících přístupových tokenů. Až se uživatel příště pokusí přihlásit, bude to muset udělat interaktivně.Do metody
DisplayBasicTokenInfopřidejte následující kód. Tato metoda zobrazí základní informace o tokenu.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; } }
Přidání kódu do souboru App.xaml.cs
App.xaml je místo, kde deklarujete prostředky, které se používají v celé aplikaci. Je to vstupní bod pro vaši aplikaci. App.xaml.cs je kód za souborem app.xaml. App.xaml.cs také definuje úvodní okno pro vaši aplikaci.
Otevřete soubor App.xaml.cs v kořenové složce aplikace a přidejte do něj následující kód.
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; } }
}
}
V tomto kroku načtete appsettings.json soubor. Tvůrce konfigurace vám pomůže číst konfigurace aplikací definované v souboru appsettings.json . Aplikaci WPF také definujete jako veřejnou klientskou aplikaci, protože se jedná o desktopovou aplikaci. Metoda TokenCacheHelper.EnableSerialization umožňuje serializaci mezipaměti tokenů.
Spuštění aplikace
Spuštění aplikace a přihlášení k otestování aplikace
V terminálu přejděte do kořenové složky aplikace WPF a spusťte aplikaci spuštěním příkazu
dotnet runv terminálu.Po spuštění ukázky by se mělo zobrazit okno s tlačítkem Přihlášení. Vyberte tlačítko Pro přihlášení.
Na přihlašovací stránce zadejte e-mailovou adresu svého účtu. Pokud účet nemáte, vyberte Žádný účet? Vytvořte jeden, který spustí tok registrace. Projděte si tento tok a vytvořte nový účet a přihlaste se.
Po přihlášení se zobrazí obrazovka s úspěšným přihlášením a základními informacemi o vašem uživatelském účtu uloženém v načteného tokenu. Základní informace se zobrazí v části Informace o tokenu na přihlašovací obrazovce.