Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Aplica-se a:
Locatários de força de trabalho
Locatários externos (saiba mais)
Este tutorial é a parte final de uma série que demonstra como criar um aplicativo shell .NET MAUI (interface do usuário do aplicativo multiplataforma) do .NET e prepará-lo para autenticação usando o centro de administração do Microsoft Entra. Na Parte 2 desta série , você adicionou um auxiliar de cliente personalizado da MSAL (Biblioteca de Autenticação da Microsoft) para inicializar o SDK da MSAL, instalar as bibliotecas necessárias e incluir um recurso de imagem. Esta etapa final demonstra como adicionar código de entrada e saída no .NET MAUI e executar o aplicativo shell na plataforma Android.
Neste tutorial, você:
- Adicione o código de entrada e de saída.
- Modifique o shell do aplicativo.
- Adicionar código específico da plataforma.
- Adicionar configurações de aplicativo.
- Execute e teste o aplicativo shell do .NET MAUI.
Pré-requisitos
Adicionar código de entrada e de saída
A interface do usuário (UI) de um aplicativo .NET MAUI é criada com objetos que são mapeados para os controles nativos de cada plataforma de destino. Os principais grupos de controle usados para criar a interface do usuário de um aplicativo MAUI do .NET são páginas, layouts e exibições.
Adicionar página de exibição principal
As próximas etapas organizarão nosso código para que main view seja definido.
Exclua MainPage.xaml e MainPage.xaml.cs do seu projeto, eles não são mais necessários. No painel Gerenciador de Soluções, localize a entrada para MainPage.xaml, clique com o botão direito do mouse e selecione Excluir.
Clique com o botão direito do mouse no projeto SignInMaui e selecione Adicionar>Nova Pasta. Nomeie a pasta Views.
Clique com o botão direito do mouse nos Modos de Exibição.
Selecione Adicionar>Novo Item....
Selecione .NET MAUI na lista de modelos.
Selecione o modelo do .NET MAUI ContentPage (XAML ). Nomeie o arquivo MainView.xaml.
Selecione Adicionar.
O arquivo MainView.xaml será aberto em uma nova guia de documento, exibindo toda a marcação XAML que representa a interface do usuário da página. Substitua a marcação XAML pela marcação a seguir:
<?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>Salve o arquivo.
Vamos especificar as partes principais dos controles XAML colocados na página:
-
<ContentPage>é o objeto raiz da classe MainView. -
<VerticalStackLayout>é o objeto filho do ContentPage. Este controle de layout organiza seus elementos filhos verticalmente, um após o outro. -
<Image>exibe uma imagem, nesse caso, ela está usando o azureactive_directory.png_ que você baixou anteriormente. -
<Label>controla o texto de exibição. -
<Button>pode ser pressionado pelo usuário, o que gera oClickedevento. Você pode executar o código em resposta ao eventoClicked. -
Clicked="OnSignInClicked"oClickedevento do botão é atribuído aoOnSignInClickedmanipulador de eventos, que será definido no arquivo code-behind. Você criará esse código na próxima etapa.
-
Manipular o evento OnSignInClicked
O próximo passo é adicionar o código do evento Clicked do botão.
No painel Gerenciador de Soluções do Visual Studio, expanda o arquivo MainView.xaml para revelar seu arquivo code-behind MainView.xaml.cs. Abra o MainView.xaml.cs e substitua o conteúdo do arquivo pelo seguinte código:
// 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; } } }A
MainViewclasse é uma página de conteúdo responsável por mostrar a visão principal do aplicativo. No construtor, ele recupera a conta de usuário armazenada em cache usandoMSALClientHelperda instânciaPublicClientSingletone habilita o botão de login, se nenhuma conta de usuário armazenada em cache for encontrada.Quando o botão de login é clicado, ele chama o método
AcquireTokenSilentAsyncpara adquirir um token silenciosamente e navega até a páginaclaimsviewusando o métodoShell.Current.GoToAsync. Além disso, o métodoOnBackButtonPressedé substituído para retornar verdadeiro, indicando que o botão voltar está desabilitado para essa exibição.
Adicionar página de visualização de declarações
As próximas etapas organizarão o código para que essa ClaimsView página seja definida. A página exibirá as declarações do usuário encontradas no token de ID.
No painel Gerenciador de Soluções do Visual Studio, clique com o botão direito do mouse nos Modos de Exibição.
Selecione Adicionar>Novo Item....
Selecione .NET MAUI na lista de modelos.
Selecione o modelo do .NET MAUI ContentPage (XAML ). Nomeie o arquivo ClaimsView.xaml.
Selecione Adicionar.
O arquivo ClaimsView.xaml será aberto em uma nova guia de documento, exibindo toda a marcação XAML que representa a interface do usuário da página. Substitua a marcação XAML pela marcação a seguir:
<?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>Esse código de marcação XAML representa o layout da interface do usuário para uma visualização de requisição em um aplicativo .NET MAUI. Ele começa definindo o
ContentPagecom um título e desabilitando o comportamento do botão voltar.Dentro de um
VerticalStackLayout, há váriosLabelelementos exibindo texto estático, seguidos por umListViewnomeClaimsque se associa a uma coleção chamadaIdTokenClaimspara exibir as declarações encontradas no token de ID. Cada declaração é renderizada dentro de umViewCellusando umDataTemplatee exibida como umLabelcentralizado dentro de uma Grade.Por fim, há um
Sign Outbotão centralizado na parte inferior do layout, que dispara oSignOutButton_Clickedmanipulador de eventos quando clicado.
Manipular os dados do ClaimsView
A próxima etapa é adicionar o código para manipular ClaimsView dados.
No painel Gerenciador de Soluções do Visual Studio, expanda o arquivo ClaimsView.xaml para revelar seu arquivo code-behind ClaimsView.xaml.cs. Abra o ClaimsView.xaml.cs e substitua o conteúdo do arquivo pelo seguinte código:
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"); } }O código ClaimsView.xaml.cs representa o código subjacente para uma exibição de reivindicação em um aplicativo MAUI do .NET. Ele começa importando os namespaces necessários e definindo a
ClaimsViewclasse, que se estendeContentPage. A propriedadeIdTokenClaimsé um enumerador de cadeias de caracteres, inicialmente definida como uma única cadeia de caracteres indicando que nenhuma declaração foi encontrada.O
ClaimsViewconstrutor define o contexto de associação para a instância atual, inicializa os componentes de exibição e chama oSetViewDataAsyncmétodo de forma assíncrona. OSetViewDataAsyncmétodo tenta adquirir um token de forma silenciosa, recupera as declarações do resultado da autenticação e define a propriedadeIdTokenClaimspara exibi-las no elementoListViewchamadoClaims. Se umMsalUiRequiredExceptionocorrer, indicando que a interação com o usuário é necessária para autenticação, o aplicativo navega até a página de declarações.O método
OnBackButtonPressedsubstitui o comportamento do botão voltar para sempre retornar verdadeiro, impedindo que o usuário volte a partir dessa exibição. OSignOutButton_Clickedmanipulador de eventos desconecta o usuário usando a instânciaPublicClientSingleton, e após concluir, navega até omain view.
Modifique o aplicativo Shell
A AppShell classe define a hierarquia visual de um aplicativo, a marcação XAML usada na criação da interface do usuário do aplicativo. Atualize o AppShell para que ele saiba sobre o Views.
Clique duas vezes no
AppShell.xamlarquivo no painel Gerenciador de Soluções para abrir o editor XAML. Substitua a marcação XAML pelo código a seguir:<?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>O código XAML define uma
AppShellclasse que desabilita o comportamento do submenu e define o conteúdo principal para umShellContentelemento com um títuloHomee um modelo de conteúdo apontando para aMainViewclasse.No painel Gerenciador de Soluções do Visual Studio, expanda o arquivo AppShell.xaml para revelar seu arquivo code-behind AppShell.xaml.cs. Abra o AppShell.xaml.cs e substitua o conteúdo do arquivo pelo seguinte código:
// 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)); } }Você atualiza o arquivo
AppShell.xaml.cspara incluir os registros de rota necessários para oMainViewe oClaimsView. Ao chamar oInitializeComponent()método, você garante a inicialização daAppShellclasse. O métodoRegisterRoute()associa as rotasmainvieweclaimsviewaos seus respectivos tipos de exibição,MainVieweClaimsView.
Adicionar código específico da plataforma
Um projeto de aplicativo .NET MAUI contém uma pasta Plataformas, com cada pasta filho representando uma plataforma que o .NET MAUI pode direcionar. Para fornecer um comportamento específico do aplicativo Android para complementar a classe de aplicativo padrão, siga estas etapas:
Clique duas vezes no
Platforms/Android/AndroidManifest.xmlarquivo no painel Gerenciador de Soluções para abrir o editor XML. Atualize as propriedades a seguir:- Defina Nome do aplicativo como MAUI CIAM.
- Defina o nome do pacote como SignInMaui.Droid.
- Defina a versão mínima do Android como Android 5.0 (API de nível 21).
Clique duas vezes no
Platforms/Android/MainActivity.csarquivo no painel Gerenciador de Soluções para abrir o editor csharp. Substitua o conteúdo do arquivo pelo seguinte código:// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using Android.App; using Android.Content; using Android.Content.PM; using Android.OS; using SignInMaui.MSALClient; using Microsoft.Identity.Client; namespace SignInMaui; [Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)] public class MainActivity : MauiAppCompatActivity { protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); // configure platform specific params PlatformConfig.Instance.RedirectUri = $"msal{PublicClientSingleton.Instance.MSALClientHelper.AzureAdConfig.ClientId}://auth"; PlatformConfig.Instance.ParentWindow = this; // Initialize MSAL and platformConfig is set _ = Task.Run(async () => await PublicClientSingleton.Instance.MSALClientHelper.InitializePublicClientAppAsync()).Result; } protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) { base.OnActivityResult(requestCode, resultCode, data); AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(requestCode, resultCode, data); } }Vamos detalhar as principais partes do código que você adicionou:
- As declarações necessárias
usingestão incluídas no topo. - A
MainActivityclasse é definida, herdando deMauiAppCompatActivity, que é a classe base para a plataforma Android no .NET MAUI. - O atributo [Activity] é aplicado à
MainActivityclasse, especificando várias configurações para a atividade do Android.-
Theme = "@style/Maui.SplashTheme"Define o tema inicial da atividade. -
MainLauncher = truedesigna esta atividade como o principal ponto de entrada do aplicativo. -
ConfigurationChangesespecifica as alterações de configuração que a atividade pode manipular, como tamanho da tela, orientação, modo de interface do usuário, layout da tela, menor tamanho de tela e densidade.
-
-
OnCreateé substituído para fornecer lógica personalizada quando a atividade está sendo criada.-
base.OnCreate(savedInstanceState)chama a implementação base do método. -
PlatformConfig.Instance.RedirectUrié definido como um valor gerado dinamicamente com base emPublicClientSingleton.Instance.MSALClientHelper.AzureAdConfig.ClientId. Ele configura o URI de redirecionamento para o cliente MSAL. -
PlatformConfig.Instance.ParentWindowé definido como a instância de atividade atual, que especifica a janela pai para operações relacionadas à autenticação. -
PublicClientSingleton.Instance.MSALClientHelper.InitializePublicClientAppAsync()inicializa o aplicativo cliente MSAL de forma assíncrona usando um método auxiliar de uma instância singleton chamadaMSALClientHelper. OTask.Runé usado para executar a inicialização em um thread em segundo plano e.Resulté usado para aguardar de forma síncrona a conclusão da tarefa.
-
-
OnActivityResulté substituído para manipular o resultado de uma atividade iniciada pela atividade atual.-
base.OnActivityResult(requestCode, resultCode, data)chama a implementação base do método. -
AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(requestCode, resultCode, data)Define os argumentos do evento de continuação de autenticação com base no código de solicitação recebido, no código de resultado e nos dados de intenção. Isso é usado para continuar o fluxo de autenticação depois que uma atividade externa retorna um resultado.
-
- As declarações necessárias
No painel Gerenciador de Soluções do Visual Studio, selecione Plataformas.
Clique com o botão direito do mouse na pasta >AndroidAdicionar>novo item....
Selecione Classe de Itens> C#. Atribua um nome ao arquivo
MsalActivity.cs.Substitua o conteúdo do
MsalActivity.csarquivo pelo seguinte código:// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; using System.Collections.Generic; using System.Linq; using System.Text; using Android.App; using Android.Content; using Android.OS; using Android.Runtime; using Android.Views; using Android.Widget; using Microsoft.Identity.Client; namespace MauiAppBasic.Platforms.Android.Resources { [Activity(Exported =true)] [IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryBrowsable, Intent.CategoryDefault }, DataHost = "auth", DataScheme = "msalEnter_the_Application_Id_Here")] public class MsalActivity : BrowserTabActivity { } }Vamos detalhar as principais partes do código que você adicionou:
-
MsalActivityclass é declarada dentro doMauiAppBasic.Platforms.Android.Resourcesnamespace. A classe herda daBrowserTabActivityclasse, indicando que ela estende sua funcionalidade. - A classe é decorada com o atributo, o
[Activity(Exported = true)]que significa que a atividade é exportada e pode ser acessada por outros métodos. - Um filtro de intent é especificado usando o atributo "[IntentFilter(...)]". Ele configura a atividade para interceptar a
ActionViewintenção. - O filtro de intent é definido para lidar com o
ActionViewintent com o (msalEnter_the_Application_Id_Here) eDataHost("auth") especificadosDataScheme. Essa configuração permite que a atividade manipule o processo de autenticação interceptando e processando aActionViewintenção. SubstituaEnter_the_Application_Id_Herepela ID do aplicativo (cliente) do aplicativo que você registrou anteriormente.
-
Adicionar configurações de aplicativo
As configurações permitem a separação de dados que configura o comportamento de um aplicativo do código, permitindo que o comportamento seja alterado sem recriar o aplicativo. O MauiAppBuilder fornece o ConfigurationManager para definir as configurações em nosso aplicativo .NET MAUI. Vamos adicionar o appsettings.json arquivo como um EmbeddedResource.
Para criar appsettings.json, siga estas etapas:
No painel Gerenciador de Soluções do Visual Studio, clique com o botão direito do mouse no projeto >Adicionar>Novo Item....
Selecione Web>JavaScript JSON Configuration File. Atribua um nome ao arquivo
appsettings.json.Selecione Adicionar.
Selecione appsettings.json
No painel Propriedades , defina a Ação de Build como recurso Inserido.
No painel Propriedades , defina Copiar para Diretório de Saída como Copiar sempre.
Substitua o conteúdo do
appsettings.jsonarquivo pelo seguinte código:{ "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" } }No
appsettings.json, encontre o espaço reservado:-
Enter_the_Tenant_Subdomain_Heree substitua-o pelo subdomínio do Diretório (locatário). Por exemplo, se o domínio primário do locatário forcontoso.onmicrosoft.com, usecontoso. Se você não tiver o nome do locatário, saiba como ler os detalhes do locatário. -
Enter_the_Application_Id_Heree substitua pela ID de Aplicativo (Cliente) do aplicativo registrado anteriormente.
-
Usar domínio de URL personalizado (opcional)
Use um domínio personalizado para marcar totalmente a URL de autenticação. Do ponto de vista do usuário, os usuários permanecem em seu domínio durante o processo de autenticação, em vez de serem redirecionados para ciamlogin.com nome de domínio.
Siga estas etapas para usar um domínio personalizado:
Use as etapas mencionadas em Habilitar domínios de URL personalizados para aplicativos de locatários externos para habilitar domínios de URL personalizados para seu locatário externo.
Abra appsettings.json arquivo:
- Atualize o valor da
Authoritypropriedade para https://Enter_the_Custom_Domain_Here/Enter_the_Tenant_ID_Here. SubstituaEnter_the_Custom_Domain_Herepelo domínio de URL personalizado eEnter_the_Tenant_ID_Herepela ID do locatário. Se você não tiver o nome do locatário, saiba como ler os detalhes do locatário. - Adicione a propriedade
knownAuthoritiescom o valor [Enter_the_Custom_Domain_Here].
- Atualize o valor da
Depois de fazer as alterações no arquivo appsettings.json, se o domínio de URL personalizado for login.contoso.com e sua ID de locatário for aaaabbbb-0000-cccc-1111-dddd2222eeee, o arquivo deverá ser semelhante ao seguinte trecho de código:
{
"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"
}
}
Executar e testar o aplicativo móvel .NET MAUI
Os aplicativos .NET MAUI são projetados para serem executados em vários sistemas operacionais e dispositivos. Você precisará selecionar qual destino deseja testar e depurar seu aplicativo.
Defina o Destino de Depuração na barra de ferramentas do Visual Studio para o dispositivo com o qual você deseja depurar e testar. As etapas a seguir demonstram a configuração do Destino de Depuração para Android:
- Selecione a lista suspensa Destino de Depuração.
- Selecione Android Emulators.
- Selecione o dispositivo emulador.
Execute o aplicativo pressionando F5 ou selecione o botão de reprodução na parte superior do Visual Studio.
Agora você pode testar o aplicativo de exemplo .NET MAUI para Android. Depois de executar o aplicativo, a janela do aplicativo Android será exibida em um emulador:
Na janela do Android que aparecer, selecione o botão Entrar. Uma janela do navegador será aberta e solicitará suas credenciais de acesso.
Durante o processo de entrada, você será solicitado a conceder várias permissões (para permitir que o aplicativo acesse seus dados). Após a entrada e o consentimento bem-sucedidos, a tela do aplicativo exibe a página principal.