Esercitazione: Concedere l’accesso utente nell'app .NET MAUI usando un tenant esterno
Questa esercitazione è la parte finale di una serie che mostra come aggiungere il codice di accesso e disconnessione alla shell .NET Multi-Platform App UI (.NET MAUI) ed eseguire l'app nella piattaforma Windows. Nella seconda parte di questa serieè stata creata un'app shell .NET MAUI, è stato aggiunto il supporto di MSAL SDK tramite le classi helper MSAL, sono state installate le librerie necessarie ed è stata inclusa una risorsa immagine. Questo passaggio finale mostra come aggiungere il codice di accesso e disconnessione alla shell .NET MAUI ed eseguire l'app nella piattaforma Windows.
In questa esercitazione apprenderai a:
- Aggiungere il codice di accesso e disconnessione.
- Modificare la shell dell'app.
- Aggiungere codice specifico per la piattaforma.
- Aggiungere le impostazioni dell'app.
- Eseguire e testare l'app shell .NET MAUI.
Prerequisiti
Aggiungere il codice di accesso e disconnessione
L'interfaccia utente di un'app .NET MAUI è costituita da oggetti che eseguono il mapping ai controlli nativi di ogni piattaforma di destinazione. I gruppi di controllo principali usati per creare l'interfaccia utente di un'app .NET MAUI sono pagine, layout e visualizzazioni.
Aggiungere la pagina della visualizzazione principale
Nei passaggi successivi viene definito il codice in modo che main view
sia definito.
Eliminare MainPage.xaml e MainPage.xaml.cs dal progetto in quanto non sono più necessari. Nel riquadro Esplora soluzioni individuare la voce MainPage.xaml, fare clic con il pulsante destro del mouse e selezionare Elimina.
Fare clic con il pulsante destro del mouse sul progetto SignInMaui e selezionare Aggiungi>Nuova cartella. Assegnare il nome Visualizzazioni alla cartella.
Fare clic con il pulsante destro del mouse su Visualizzazioni.
Selezionare Aggiungi>Nuovo elemento....
Selezionare .NET MAUI nell'elenco dei modelli.
Selezionare il modello .NET MAUI ContentPage (XAML). Assegnare il nome MainView.xaml al file.
Selezionare Aggiungi.
Il file MainView.xaml verrà aperto in una nuova scheda del documento, visualizzando tutto il markup XAML che rappresenta l'interfaccia utente della pagina. Sostituire il markup XAML con il markup seguente:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="SignInMaui.Views.MainView" Title="Microsoft Entra External ID" > <Shell.BackButtonBehavior> <BackButtonBehavior IsVisible="False" IsEnabled="False" /> </Shell.BackButtonBehavior> <ScrollView> <VerticalStackLayout Spacing="25" Padding="30,0" VerticalOptions="Center"> <Image Source="external_id.png" SemanticProperties.Description="External ID" HeightRequest="200" HorizontalOptions="Center" /> <Label Text="CIAM" SemanticProperties.HeadingLevel="Level1" FontSize="26" HorizontalOptions="Center" /> <Label Text="MAUI sample" SemanticProperties.HeadingLevel="Level1" FontSize="26" HorizontalOptions="Center" /> <Button x:Name="SignInButton" Text="Sign In" SemanticProperties.Hint="Sign In" Clicked="OnSignInClicked" HorizontalOptions="Center" IsEnabled="False"/> </VerticalStackLayout> </ScrollView> </ContentPage>
Salvare il file.
Suddividere le parti principali dei controlli XAML presenti nella pagina:
<ContentPage>
è l'oggetto radice per la classe MainView.<VerticalStackLayout>
è l'oggetto figlio di ContentPage. Questo controllo di layout dispone verticalmente gli elementi figlio, uno dopo l'altro.<Image>
visualizza un’immagine, in questo caso usando azureactive_directory.png_ scaricato in precedenza.<Label>
controlla il testo da visualizzare.<Button>
può essere premuto dall'utente per generare l'eventoClicked
. È possibile eseguire il codice in risposta all'eventoClicked
.Clicked="OnSignInClicked"
l'eventoClicked
del pulsante viene assegnato al gestore eventiOnSignInClicked
, che verrà definito nel file code-behind. Questo codice verrà creato nel passaggio successivo.
Gestire l'evento OnSignInClicked
Il passaggio successivo consiste nell'aggiungere il codice per l'evento Clicked
del pulsante.
Nel riquadro Esplora soluzioni di Visual Studio espandere il file MainView.xaml per visualizzare il file code-behind MainView.xaml.cs. Aprire il file MainView.xaml.cs e sostituire il contenuto del file con il codice seguente:
// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using SignInMaui.MSALClient; using Microsoft.Identity.Client; namespace SignInMaui.Views { public partial class MainView : ContentPage { public MainView() { InitializeComponent(); IAccount cachedUserAccount = PublicClientSingleton.Instance.MSALClientHelper.FetchSignedInUserFromCache().Result; _ = Dispatcher.DispatchAsync(async () => { if (cachedUserAccount == null) { SignInButton.IsEnabled = true; } else { await Shell.Current.GoToAsync("claimsview"); } }); } private async void OnSignInClicked(object sender, EventArgs e) { await PublicClientSingleton.Instance.AcquireTokenSilentAsync(); await Shell.Current.GoToAsync("claimsview"); } protected override bool OnBackButtonPressed() { return true; } } }
La classe MainView
è una pagina di contenuto responsabile della visualizzazione della finestra principale dell'app. Nel costruttore recupera l'account utente memorizzato nella cache usando MSALClientHelper
dall'istanza PublicClientSingleton
e abilita il pulsante di accesso, se non trova alcun account utente memorizzato nella cache.
Quando si fa clic sul pulsante di accesso, chiama il metodo AcquireTokenSilentAsync
per acquisire un token in modo invisibile all'utente e passa alla pagina claimsview
usando il metodo Shell.Current.GoToAsync
. Inoltre, viene eseguito l’override del metodo OnBackButtonPressed
in modo che restituisca true, a indicare che il pulsante Indietro è disabilitato per l visualizzazione.
Pagina Aggiungi visualizzazione delle attestazioni
Nei passaggi successivi il codice viene organizzato in modo che venga definita la pagina ClaimsView
. La pagina visualizzerà le attestazioni dell'utente trovate nel token ID.
Nel riquadro Esplora soluzioni di Visual Studio fare clic con il pulsante destro del mouse su Visualizzazioni.
Selezionare Aggiungi>Nuovo elemento....
Selezionare .NET MAUI nell'elenco dei modelli.
Selezionare il modello .NET MAUI ContentPage (XAML). Assegnare il nome ClaimsView.xaml al file.
Selezionare Aggiungi.
Il file ClaimsView.xaml verrà aperto in una nuova scheda del documento, visualizzando tutto il markup XAML che rappresenta l'interfaccia utente della pagina. Sostituire il markup XAML con il markup seguente:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="SignInMaui.Views.ClaimsView" Title="ID Token View"> <Shell.BackButtonBehavior> <BackButtonBehavior IsVisible="False" IsEnabled="False" /> </Shell.BackButtonBehavior> <VerticalStackLayout> <Label Text="CIAM" FontSize="26" HorizontalOptions="Center" /> <Label Text="MAUI sample" FontSize="26" Padding="0,0,0,20" HorizontalOptions="Center" /> <Label Padding="0,20,0,0" VerticalOptions="Center" HorizontalOptions="Center" FontSize="18" Text="Claims found in ID token" /> <ListView ItemsSource="{Binding IdTokenClaims}" x:Name="Claims"> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <Grid Padding="0, 0, 0, 0"> <Label Grid.Column="1" Text="{Binding}" HorizontalOptions="Center" /> </Grid> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView> <Button x:Name="SignOutButton" Text="Sign Out" HorizontalOptions="Center" Clicked="SignOutButton_Clicked" /> </VerticalStackLayout> </ContentPage>
Questo codice di markup XAML rappresenta il layout dell'interfaccia utente per una visualizzazione delle attestazioni in un'app .NET MAUI. Inizia definendo
ContentPage
con un titolo e disabilitando il comportamento del pulsante Indietro.All'interno di
VerticalStackLayout
sono presenti diversi elementiLabel
che visualizzano testo statico, seguito da unListView
denominatoClaims
che si associa a una raccolta denominataIdTokenClaims
per visualizzare le attestazioni trovate nel token ID. Viene eseguito il rendering di ogni attestazione all'interno di unViewCell
usando unDataTemplate
e ogni attestazione viene visualizzata come un’Label
centrato all'interno di una griglia.Infine, è presente un pulsante
Sign Out
centrato nella parte inferiore del layout, che attiva il gestore eventiSignOutButton_Clicked
quando viene selezionato con il mouse.
Gestire i dati ClaimsView
Il passaggio successivo consiste nell'aggiungere il codice per gestire i dati ClaimsView
.
Nel riquadro Esplora soluzioni di Visual Studio espandere il file ClaimsView.xaml per visualizzare il file code-behind ClaimsView.xaml.cs. Aprire il file ClaimsView.xaml.cs e sostituire il contenuto del file con il codice seguente:
using SignInMaui.MSALClient; using Microsoft.Identity.Client; namespace SignInMaui.Views; public partial class ClaimsView : ContentPage { public IEnumerable<string> IdTokenClaims { get; set; } = new string[] {"No claims found in ID token"}; public ClaimsView() { BindingContext = this; InitializeComponent(); _ = SetViewDataAsync(); } private async Task SetViewDataAsync() { try { _ = await PublicClientSingleton.Instance.AcquireTokenSilentAsync(); IdTokenClaims = PublicClientSingleton.Instance.MSALClientHelper.AuthResult.ClaimsPrincipal.Claims.Select(c => c.Value); Claims.ItemsSource = IdTokenClaims; } catch (MsalUiRequiredException) { await Shell.Current.GoToAsync("claimsview"); } } protected override bool OnBackButtonPressed() { return true; } private async void SignOutButton_Clicked(object sender, EventArgs e) { await PublicClientSingleton.Instance.SignOutAsync().ContinueWith((t) => { return Task.CompletedTask; }); await Shell.Current.GoToAsync("mainview"); } }
Il codice ClaimsView.xaml.cs rappresenta il code-behind per una visualizzazione delle attestazioni in un'app .NET MAUI. Inizia importando gli spazi dei nomi necessari e definendo la classe
ClaimsView
che estendeContentPage
. La proprietàIdTokenClaims
è un elenco enumerabile di stringhe, inizialmente impostata su una singola stringa che indica che non sono state trovate attestazioni.Il costruttore
ClaimsView
imposta il contesto di associazione sull'istanza corrente, inizializza i componenti di visualizzazione e chiama il metodoSetViewDataAsync
in modo asincrono. Il metodoSetViewDataAsync
tenta di acquisire un token in modo invisibile all'utente, recupera le attestazioni dal risultato dell'autenticazione e imposta la proprietàIdTokenClaims
per visualizzare le attestazioni nell'oggettoListView
denominatoClaims
. Se si verifica unMsalUiRequiredException
, a indicare che l'interazione dell'utente è necessaria per l'autenticazione, l'app passa alla visualizzazione delle attestazioni.Il metodo
OnBackButtonPressed
esegue l'override del comportamento del pulsante Indietro per restituire sempre true, impedendo all'utente di tornare a questa visualizzazione. Il gestore eventiSignOutButton_Clicked
disconnette l'utente usando l'istanzaPublicClientSingleton
e, al termine, passa amain view
.
Modificare la shell dell'app
La classe AppShell
definisce la gerarchia visiva di un'app, il markup XAML usato per creare l'interfaccia utente dell'app. Aggiornare AppShell
per segnalarlo a Views
.
Fare doppio clic sul file
AppShell.xaml
nel riquadro Esplora soluzioni per aprire l'editor XAML. Sostituire il markup XAML con il codice seguente:<?xml version="1.0" encoding="UTF-8" ?> <Shell x:Class="SignInMaui.AppShell" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:SignInMaui.Views" Shell.FlyoutBehavior="Disabled"> <ShellContent Title="Home" ContentTemplate="{DataTemplate local:MainView}" Route="MainPage" /> </Shell>
Il codice XAML definisce una classe
AppShell
che disabilita il comportamento del riquadro a comparsa e imposta il contenuto principale su un elementoShellContent
con un titoloHome
e un modello di contenuto che punta alla classeMainView
.Nel riquadro Esplora soluzioni di Visual Studio espandere il file AppShell.xaml per visualizzare il file code-behind AppShell.xaml.cs. Aprire il file AppShell.xaml.cs e sostituire il contenuto del file con il codice seguente:
// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using SignInMaui.Views; namespace SignInMaui; public partial class AppShell : Shell { public AppShell() { InitializeComponent(); Routing.RegisterRoute("mainview", typeof(MainView)); Routing.RegisterRoute("claimsview", typeof(ClaimsView)); } }
Aggiornare il file
AppShell.xaml.cs
in modo da includere le registrazioni di route necessarie perMainView
eClaimsView
. La chiamata del metodoInitializeComponent()
permette di assicurarsi che la classeAppShell
venga inizializzata. Il metodoRegisterRoute()
associa le routemainview
eclaimsview
ai rispettivi tipi di visualizzazione,MainView
eClaimsView
.
Aggiungere codice specifico per la piattaforma
Un progetto di app .NET MAUI contiene una cartella Platforms, in cui ogni cartella figlio rappresenta una piattaforma in cui è possibile eseguire .NET MAUI. Per fornire un comportamento specifico per l’applicazione in supplemento alla classe Application predefinita, è necessario modificare Platforms/Windows/App.xaml.cs
.
Sostituire il contenuto del file con il codice seguente:
using SignInMaui.MSALClient;
using Microsoft.Identity.Client;
using Microsoft.UI.Xaml;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace SignInMaui.WinUI;
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
public partial class App : MauiWinUIApplication
{
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
this.InitializeComponent();
// configure redirect URI for your application
PlatformConfig.Instance.RedirectUri = $"msal{PublicClientSingleton.Instance.MSALClientHelper.AzureAdConfig.ClientId}://auth";
// Initialize MSAL
IAccount existinguser = Task.Run(async () => await PublicClientSingleton.Instance.MSALClientHelper.InitializePublicClientAppAsync()).Result;
}
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
base.OnLaunched(args);
var app = SignInMaui.App.Current;
PlatformConfig.Instance.ParentWindow = ((MauiWinUIWindow)app.Windows[0].Handler.PlatformView).WindowHandle;
}
}
Nel codice, è necessario configurare l'URI di reindirizzamento per l'applicazione e inizializzare MSAL e quindi impostare la finestra padre per l'applicazione. Inoltre, è necessario eseguire l'override del metodo OnLaunched
per gestire l'evento di avvio e recuperare l'handle della finestra padre.
Aggiungere le impostazioni dell'app
Le impostazioni consentono la separazione dei dati che configurano il comportamento di un'app dal codice, consentendo la modifica del comportamento senza ricompilare l'app. MauiAppBuilder
fornisce ConfigurationManager
per la configurazione delle impostazioni nell'app .NET MAUI. Aggiungere il file appsettings.json
come EmbeddedResource
.
Per creare appsettings.json
, seguire questa procedura:
Nel riquadro Esplora soluzioni di Visual Studio, fare clic con il pulsante destro del mouse sul progetto SignInMaui>Aggiungi>Nuovo elemento....
Selezionare Web>File di configurazione JSON per JavaScript. Denominare il file
appsettings.json
.Selezionare Aggiungi.
Selezionare appsettings.json
Nel riquadro Proprietà impostare Operazione di compilazione su Risorsa incorporata.
Nel riquadro Proprietà impostare Copia in directory di output su Copia sempre.
Sostituire il contenuto del file
appsettings.json
con il codice seguente:{ "AzureAd": { "Authority": "https://Enter_the_Tenant_Subdomain_Here.ciamlogin.com/", "ClientId": "Enter_the_Application_Id_Here", "CacheFileName": "msal_cache.txt", "CacheDir": "C:/temp" }, "DownstreamApi": { "Scopes": "openid offline_access" } }
In
appsettings.json
trovare il segnaposto:Enter_the_Tenant_Subdomain_Here
e sostituirlo con il sottodominio della directory (tenant). Ad esempio, se il dominio primario del tenant ècontoso.onmicrosoft.com
, usarecontoso
. Se non si ha il nome del tenant, vedere come leggere i dettagli del tenant.Enter_the_Application_Id_Here
e sostituirlo con l'ID applicazione (client) dell’app registrato in precedenza.
Usare un dominio URL personalizzato (facoltativo)
Usare un dominio personalizzato per personalizzare completamente l'URL di autenticazione. Dal punto di vista dell'utente, gli utenti rimangono nel dominio durante il processo di autenticazione, anziché essere reindirizzati a ciamlogin.com nome di dominio.
Per usare un dominio personalizzato, seguire questa procedura:
Usare la procedura descritta in Abilitare domini URL personalizzati per le app nei tenant esterni per abilitare il dominio URL personalizzato per il tenant esterno.
Aprire il file appsettings.json.
- Aggiornare il valore della proprietà da
Authority
a https://Enter_the_Custom_Domain_Here/Enter_the_Tenant_ID_Here. SostituireEnter_the_Custom_Domain_Here
con il dominio URL personalizzato eEnter_the_Tenant_ID_Here
con l'ID tenant. Se non si ha l’ID del tenant, vedere come leggere i dettagli del tenant. - Aggiungere una proprietà
knownAuthorities
con un valore [Enter_the_Custom_Domain_Here].
- Aggiornare il valore della proprietà da
Dopo aver apportato le modifiche al file appsettings.json, se il dominio URL personalizzato è login.contoso.com e l'ID tenant è aaaabbbbbb-0000-cccc-1111-dddd2222eee, allora il file sarà simile al frammento di codice seguente:
{
"AzureAd": {
"Authority": "https://login.contoso.com/aaaabbbb-0000-cccc-1111-dddd2222eeee",
"ClientId": "Enter_the_Application_Id_Here",
"CacheFileName": "msal_cache.txt",
"CacheDir": "C:/temp",
"KnownAuthorities": ["login.contoso.com"]
},
"DownstreamApi": {
"Scopes": "openid offline_access"
}
}
Eseguire e testare l'app desktop .NET MAUI
Le app .NET MAUI sono progettate per essere eseguite in più sistemi operativi e dispositivi. È necessario selezionare la destinazione che si desidera usare per testare ed eseguire il debug dell'app.
Impostare la destinazione di debug nella barra degli strumenti di Visual Studio sul dispositivo con cui si vuole eseguire il debug e il test. I passaggi seguenti mostrano come impostare la destinazione di debug su Windows:
- Selezionare l’elenco a discesa Destinazione di debug.
- Selezionare Framework
- Selezionare net7.0-windows...
Eseguire l'app premendo F5 o selezionando il pulsante di riproduzione nella parte superiore di Visual Studio.
È ora possibile testare l'applicazione desktop .NET MAUI di esempio. Dopo aver eseguito l'applicazione, viene automaticamente visualizzata la finestra dell'applicazione desktop:
Nella finestra desktop visualizzata, selezionare il pulsante Accedi. Si apre una finestra del browser e viene richiesto di eseguire l'accesso.
Durante il processo di accesso viene richiesto di concedere varie autorizzazioni (per consentire all'applicazione di accedere ai dati dell’utente). Al termine dell'accesso e del consenso, la schermata dell'applicazione visualizza la pagina principale.