Adicionar autenticação ao aplicativo do Windows (WPF)

Nota

Este produto está desativado. Para obter uma substituição para projetos que usam o .NET 8 ou posterior, consulte a biblioteca datasync do Kit de Ferramentas da Comunidade .

Neste tutorial, você adicionará a autenticação da Microsoft ao projeto TodoApp usando a ID do Microsoft Entra. Antes de concluir este tutorial, verifique se você criou o projeto e implantou ode back-end.

Ponta

Embora usemos a ID do Microsoft Entra para autenticação, você pode usar qualquer biblioteca de autenticação desejada com os Aplicativos Móveis do Azure.

Adicionar autenticação ao serviço de back-end

Seu serviço de back-end é um serviço padrão ASP.NET 6. Qualquer tutorial que mostre como habilitar a autenticação para um serviço ASP.NET 6 funciona com os Aplicativos Móveis do Azure.

Para habilitar a autenticação do Microsoft Entra para seu serviço de back-end, você precisa:

  • Registre um aplicativo com a ID do Microsoft Entra.
  • Adicione a verificação de autenticação ao projeto de back-end do ASP.NET 6.

Registrar o aplicativo

Primeiro, registre a API Web em seu locatário do Microsoft Entra e adicione um escopo seguindo estas etapas:

  1. Entre no portal do do Azure.

  2. Se você tiver acesso a vários locatários, use o Directories + assinaturas filtro no menu superior para alternar para o locatário no qual deseja registrar o aplicativo.

  3. Pesquise e selecione microsoft entra ID.

  4. Em Gerenciar, selecione Registros de aplicativo>Novo registro.

    • Name: insira um nome para seu aplicativo; por exemplo, início rápido do TodoApp. Os usuários do seu aplicativo verão esse nome. Você pode alterá-lo mais tarde.
    • tipos de conta com suporte: contas em qualquer diretório organizacional (qualquer diretório do Microsoft Entra – Multilocatário) e contas pessoais da Microsoft (por exemplo, Skype, Xbox)
  5. Selecione Registrar.

  6. Em Gerenciar, selecione Expor uma API>Adicionar um escopo.

  7. Para de URI da ID do Aplicativo, aceite o padrão selecionando Salvar e continuar.

  8. Insira os seguintes detalhes:

    • de nome do escopo :
    • Quem pode consentir?: administradores e usuários
    • nome de exibição de consentimento do administrador: Access TodoApp
    • descrição de consentimento do administrador: Allows the app to access TodoApp as the signed-in user.
    • nome de exibição de consentimento do usuário: Access TodoApp
    • descrição de consentimento do usuário: Allow the app to access TodoApp on your behalf.
    • State: enabled
  9. Selecione Adicionar de escopo para concluir a adição de escopo.

  10. Observe o valor do escopo, semelhante a (conhecido como escopo da API Web). Você precisa do escopo ao configurar o cliente.

  11. Selecione visão geral.

  12. Observe a de ID do aplicativo (cliente) na seção do Essentials (conhecida comoda ID do aplicativo da API Web ). Você precisa desse valor para configurar o serviço de back-end.

Abra o Visual Studio e selecione o projeto TodoAppService.NET6.

  1. Clique com o botão direito do mouse no projeto TodoAppService.NET6 e selecione Gerenciar Pacotes NuGet....

  2. Na nova guia, selecione Procurare, em seguida, insira Microsoft.Identity.Web na caixa de pesquisa.

    captura de tela da adição do NuGet M S A L no Visual Studio.

  3. Selecione o pacote Microsoft.Identity.Web e pressione Instalar.

  4. Siga os prompts para concluir a instalação do pacote.

  5. Abra Program.cs. Adicione o seguinte à lista de instruções using:

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
  1. Adicione o seguinte código diretamente acima da chamada para builder.Services.AddDbContext():
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
  .AddMicrosoftIdentityWebApi(builder.Configuration);
builder.Services.AddAuthorization();
  1. Adicione o seguinte código diretamente acima da chamada para app.MapControllers():
app.UseAuthentication();
app.UseAuthorization();

Seu Program.cs agora deve ter esta aparência:

using Microsoft.AspNetCore.Datasync;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
using TodoAppService.NET6.Db;
  
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
  
if (connectionString == null)
{
  throw new ApplicationException("DefaultConnection is not set");
}
  
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
  .AddMicrosoftIdentityWebApi(builder.Configuration);
builder.Services.AddAuthorization();
builder.Services.AddDbContext<AppDbContext>(options => options.UseSqlServer(connectionString));
builder.Services.AddDatasyncControllers();
  
var app = builder.Build();
  
// Initialize the database
using (var scope = app.Services.CreateScope())
{
  var context = scope.ServiceProvider.GetRequiredService<AppDbContext>();
  await context.InitializeDatabaseAsync().ConfigureAwait(false);
}
  
// Configure and run the web service.
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
  1. Edite o Controllers\TodoItemController.cs. Adicione um atributo [Authorize] à classe. Sua classe deve ter esta aparência:
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Datasync;
using Microsoft.AspNetCore.Datasync.EFCore;
using Microsoft.AspNetCore.Mvc;
using TodoAppService.NET6.Db;

namespace TodoAppService.NET6.Controllers
{
  [Authorize]
  [Route("tables/todoitem")]
  public class TodoItemController : TableController<TodoItem>
  {
    public TodoItemController(AppDbContext context)
      : base(new EntityTableRepository<TodoItem>(context))
    {
    }
  }
}
  1. Edite o appsettings.json. Adicione o seguinte bloco:
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com",
    "ClientId": "<client-id>",
    "TenantId": "common"
  },

Substitua o <client-id> pela ID do aplicativo da API Web que você registrou anteriormente. Depois de concluído, ele deverá ter esta aparência:

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com",
    "ClientId": "<client-id>",
    "TenantId": "common"
  },
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=TodoApp;Trusted_Connection=True"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}

Publique seu serviço no Azure novamente:

  1. Clique com o botão direito do mouse no projeto TodoAppService.NET6 e selecione Publicar....
  2. Selecione o botão Publicar no canto superior direito da guia.

Abra um navegador para https://yoursite.azurewebsites.net/tables/todoitem?ZUMO-API-VERSION=3.0.0. Observe que o serviço agora retorna uma resposta 401, que indica que a autenticação é necessária.

Captura de tela do navegador mostrando um erro.

Registrar seu aplicativo com o serviço de identidade

O Microsoft Data sync Framework tem suporte interno para qualquer provedor de autenticação que usa um JWT (Token Web Json) dentro de um cabeçalho da transação HTTP. Esse aplicativo usa o da MSAL (Biblioteca de Autenticação da Microsoft) para solicitar esse token e autorizar o usuário conectado ao serviço de back-end.

Configurar um aplicativo cliente nativo

Você pode registrar clientes nativos para permitir a autenticação em APIs Web hospedadas em seu aplicativo usando uma biblioteca de clientes, como a MSAL (Biblioteca de Identidades da Microsoft).

  1. No portal do do Azure, selecione registros de ID do Microsoft Entra>App>Novo registro.

  2. Na página Registrar um aplicativo:

    • insira um Name para o registro do aplicativo. Talvez você queira usar o nome native-quickstart para distinguir este do usado pelo serviço de back-end.
    • Selecione Contas em qualquer diretório organizacional (qualquer diretório do Microsoft Entra – Multilocatário) e contas pessoais da Microsoft (por exemplo, Skype, Xbox).
    • Em de URI de Redirecionamento:
      • Selecione cliente público (área de trabalho de & móvel)
      • Insira o quickstart://auth de URL
  3. Selecione Registrar.

  4. Selecione permissões de API>Adicionar uma permissão>minhas APIs.

  5. Selecione o registro de aplicativo criado anteriormente para seu serviço de back-end. Se você não vir o registro do aplicativo, verifique se adicionou o escopo access_as_user.

    Captura de tela do registro de escopo no portal do Azure.

  6. Em Selecione permissões, selecione access_as_usere selecione Adicionar permissões.

  7. Selecionede aplicativosmóveis e de área de trabalho da Autenticação .

  8. Marque a caixa ao lado de https://login.microsoftonline.com/common/oauth2/nativeclient.

  9. Marque a caixa ao lado de msal{client-id}://auth (substituindo {client-id} pela ID do aplicativo).

  10. Selecione Adicionarde URI e, em seguida, adicione http://localhost no campo para URIs extras.

  11. Selecione Salvar na parte inferior da página.

  12. Selecione visão geral. Anote a ID do aplicativo (cliente) (conhecida como ID do aplicativo do cliente nativo), pois você precisa dele para configurar o aplicativo móvel.

Definimos três URLs de redirecionamento:

  • http://localhost é usado por aplicativos WPF.
  • https://login.microsoftonline.com/common/oauth2/nativeclient é usado por aplicativos UWP.
  • msal{client-id}://auth é usado por aplicativos móveis (Android e iOS).

Adicionar o Cliente de Identidade da Microsoft ao seu aplicativo

Abra a solução TodoApp.sln no Visual Studio e defina o projeto TodoApp.WPFcomo o projeto de inicialização. Adicione o da MSAL (Biblioteca de Identidades da Microsoft) ao projeto :

Adicione o da MSAL (Biblioteca de Identidades da Microsoft) ao projeto da plataforma:

  1. Clique com o botão direito do mouse no projeto e selecione Gerenciar Pacotes NuGet....

  2. Selecione a guia Procurar.

  3. Insira Microsoft.Identity.Client na caixa de pesquisa e pressione Enter.

  4. Selecione o resultado do Microsoft.Identity.Client e clique em Instalar.

    Captura de tela da seleção do NuGet msal no Visual Studio.

  5. Aceite o contrato de licença para continuar a instalação.

Adicione a ID do cliente nativo e o escopo de back-end à configuração.

Abra o projeto TodoApp.Data e edite o arquivo Constants.cs. Adicionar constantes para ApplicationId e Scopes:

  public static class Constants
  {
      /// <summary>
      /// The base URI for the Datasync service.
      /// </summary>
      public static string ServiceUri = "https://demo-datasync-quickstart.azurewebsites.net";

      /// <summary>
      /// The application (client) ID for the native app within Microsoft Entra ID
      /// </summary>
      public static string ApplicationId = "<client-id>";

      /// <summary>
      /// The list of scopes to request
      /// </summary>
      public static string[] Scopes = new[]
      {
          "<scope>"
      };
  }

Substitua o <client-id> pela ID do aplicativo Native Client você recebeu ao registrar o aplicativo cliente na ID do Microsoft Entra e o <scope> com o Escopo da API Web copiado quando você usou Expor um de API ao registrar o aplicativo de serviço.

Abra o arquivo App.xaml.cs no projeto TodoApp.WPF.

Adicione as seguintes instruções using à parte superior do arquivo:

using Microsoft.Datasync.Client;
using Microsoft.Identity.Client;
using System.Diagnostics;
using System.Linq;

Remova a propriedade TodoService e substitua-a pelo seguinte código:

static App()
{
    IdentityClient = PublicClientApplicationBuilder.Create(Constants.ApplicationId)
        .WithAuthority(AzureCloudInstance.AzurePublic, "common")
        .WithRedirectUri("http://localhost")
        .Build();
    TodoService = new RemoteTodoService(async () => await GetAuthenticationToken());
}

public static IPublicClientApplication IdentityClient { get; }

public static ITodoService TodoService { get; }

public static async Task<AuthenticationToken> GetAuthenticationToken()
{
    var accounts = await IdentityClient.GetAccountsAsync();
    AuthenticationResult? result = null;
    try
    {
        result = await IdentityClient
            .AcquireTokenSilent(Constants.Scopes, accounts.FirstOrDefault())
            .ExecuteAsync();
    }
    catch (MsalUiRequiredException)
    {
        result = await IdentityClient
            .AcquireTokenInteractive(Constants.Scopes)
            .ExecuteAsync();
    }
    catch (Exception ex)
    {
        // Display the error text - probably as a pop-up
        Debug.WriteLine($"Error: Authentication failed: {ex.Message}");
    }

    return new AuthenticationToken
    {
        DisplayName = result?.Account?.Username ?? "",
        ExpiresOn = result?.ExpiresOn ?? DateTimeOffset.MinValue,
        Token = result?.AccessToken ?? "",
        UserId = result?.Account?.Username ?? ""
    };
}

O método GetAuthenticationToken() funciona com a MSAL (Biblioteca de Identidade da Microsoft) para obter um token de acesso adequado para autorizar o usuário conectado ao serviço de back-end. Em seguida, essa função é passada para o RemoteTodoService para criar o cliente. Se a autenticação for bem-sucedida, o AuthenticationToken será produzido com os dados necessários para autorizar cada solicitação. Caso contrário, um token inválido expirado será produzido.

Testar o aplicativo

Você deve ser capaz de pressionar F5 para executar o aplicativo. Quando o aplicativo é executado, um navegador é aberto para solicitar autenticação. Na primeira vez que o aplicativo for executado, você será solicitado a consentir com o acesso:

Captura de tela da solicitação de consentimento do Microsoft Entra.

Pressione Sim para continuar no aplicativo.

Próximas etapas

Em seguida, configure seu aplicativo para operar offline implementando um repositório offline.

Leitura adicional