Adicionar autenticação ao aplicativo Xamarin.iOS

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

Observação

Como o aplicativo iOS requer acesso às chaves, você precisará configurar um perfil de provisionamento do iOS. Um perfil de provisionamento requer um dispositivo iOS real ou uma conta de desenvolvedor Apple paga (se estiver usando o simulador). Você pode ignorar este tutorial e passar para a adição de acesso off-line ao seu aplicativo se não puder usar a autenticação devido a essa restrição.

Dica

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

Adicionar autenticação ao seu 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 o Microsoft Entra ID.
  • Adicione a verificação de autenticação ao projeto de back-end do ASP.NET 6.

Registrar o aplicativo

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

  1. Entre no portal do Azure.

  2. Se você tiver acesso a vários locatários, use o filtro Diretórios + assinaturas 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.

    • Nome: insira um nome para seu aplicativo, por exemplo, Guia de início rápido do TodoApp. Os usuários do seu aplicativo verão esse nome. Você pode alterar isso mais tarde.
    • Tipos de conta suportados: 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 URI de ID do Aplicativo, aceite o padrão selecionando Salvar e continuar.

  8. Insira os seguintes detalhes:

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

  10. Observe o valor do escopo, semelhante a api://<client-id>/access_as_user (conhecido como Escopo da API da Web). Você precisa do escopo ao configurar o cliente.

  11. Selecione Visão geral.

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

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

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

  2. Na nova guia, selecione Procurar e digite Microsoft.Identity.Web na caixa de pesquisa.

    Screenshot of adding the M S A L NuGet in Visual Studio.

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

  4. Siga as instruções para concluir a instalação do pacote.

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

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 deve se parecer com este:

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.csarquivo . Adicione um [Authorize] atributo à classe. Sua classe deve ter a seguinte 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.jsonarquivo . Adicione o seguinte bloco:
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com",
    "ClientId": "<client-id>",
    "TenantId": "common"
  },

Substitua o <client-id> pelo ID do Aplicativo de API Web que você registrou anteriormente. Depois de concluído, ele deve ter a seguinte 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 TodoAppService.NET6 mouse no projeto 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 401 resposta, que indica que a autenticação é necessária.

Screenshot of the browser showing an error.

Registrar seu aplicativo com o serviço de identidade

O Microsoft Data Sync Framework tem suporte interno para qualquer provedor de autenticação que use um JWT (Json Web Token) em um cabeçalho da transação HTTP. Este aplicativo usa a Microsoft Authentication Library (MSAL) para solicitar esse token e autorizar o usuário conectado ao serviço de back-end.

Configurar um aplicativo de cliente nativo

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

  1. No portal do Azure, selecione Registros do aplicativo ID>do> Microsoft Entra Novo registro.

  2. Na página Registrar um aplicativo:

    • insira um Nome para o registro do aplicativo. Você pode usar o nome native-quickstart para distinguir este do usado pelo seu 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).
    • No URI de redirecionamento:
      • Selecionar cliente público (móvel e desktop)
      • Digite a URL quickstart://auth
  3. Selecione Registrar.

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

  5. Selecione o registro de aplicativo que você criou anteriormente para seu serviço de back-end. Se você não vir o registro do aplicativo, certifique-se de ter adicionado o escopo access_as_user.

    Screenshot of the scope registration in the Azure portal.

  6. Em Selecionar permissões, selecione access_as_user e, em seguida, selecione Adicionar permissões.

  7. Selecione Autenticação>de aplicativos móveis e de desktop.

  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 Adicionar URI e, em seguida, adicione http://localhost no campo para URIs extras.

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

  12. Selecione Visão geral. Anote a ID do Aplicativo (cliente) (conhecida como ID do Aplicativo Cliente Nativo) conforme necessário 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 Microsoft Identity Client ao seu aplicativo

Abra a TodoApp.sln solução no Visual Studio e defina o projeto como o TodoApp.iOS projeto de inicialização. Adicione a Microsoft Identity Library (MSAL) ao TodoApp.iOS projeto:

Adicione a Microsoft Identity Library (MSAL) ao projeto de 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 Microsoft.Identity.Client e clique em Instalar.

    Screenshot of selecting the MSAL NuGet in Visual Studio.

  5. Aceite o contrato de licença e continue a instalação.

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

Abra o projeto e edite o TodoApp.DataConstants.cs arquivo. Adicione 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 pelo ID do Aplicativo Cliente Nativo que você recebeu ao registrar o aplicativo cliente no Microsoft Entra ID e pelo <scope> Escopo da API Web que você copiou quando usou Expor uma API ao registrar o <client-id> aplicativo de serviço.

Aberto ViewControllers\HomeViewController.cs no TodoApp.iOS projeto. Adicione as seguintes declarações de using :

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

HomeViewController Na classe, adicione uma nova propriedade:

public IPublicClientApplication IdentityClient { get; set; }

Ajuste o construtor para ler:

public HomeViewController() {
  Title = "Todo Items";
  TodoService = new RemoteTodoService(GetAuthenticationToken);
  TodoService.TodoItemsUpdated += OnTodoItemsUpdated;
}

Adicione o método GetAuthenticationToken à classe:

public async Task<AuthenticationToken> GetAuthenticationToken()
{
    if (IdentityClient == null)
    {
        IdentityClient = PublicClientApplicationBuilder.Create(Constants.ApplicationId)
            .WithAuthority(AzureCloudInstance.AzurePublic, "common")
            .WithRedirectUri($"msal{Constants.ApplicationId}://auth")
            .WithIosKeychainSecurityGroup("com.microsoft.adalcache")
            .Build();
    }

    var accounts = await IdentityClient.GetAccountsAsync();
    AuthenticationResult result = null;
    bool tryInteractiveLogin = false;

    try
    {
        result = await IdentityClient
            .AcquireTokenSilent(Constants.Scopes, accounts.FirstOrDefault())
            .ExecuteAsync();
    }
    catch (MsalUiRequiredException)
    {
        tryInteractiveLogin = true;
    }
    catch (Exception ex)
    {
        Debug.WriteLine($"MSAL Silent Error: {ex.Message}");
    }

    if (tryInteractiveLogin)
    {
        try
        {
            result = await IdentityClient
                .AcquireTokenInteractive(Constants.Scopes)
                .ExecuteAsync()
                .ConfigureAwait(false);
        }
        catch (Exception ex)
        {
            Debug.WriteLine($"MSAL Interactive Error: {ex.Message}");
        }
    }

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

O GetAuthenticationToken() método funciona com o Microsoft Identity Library (MSAL) para obter um token de acesso adequado para autorizar o usuário conectado ao serviço de back-end. Essa função é então passada para o para criar o RemoteTodoService cliente. Se a autenticação for bem-sucedida, o é produzido com os AuthenticationToken dados necessários para autorizar cada solicitação. Caso contrário, um token incorreto expirado é produzido.

Adicione o seguinte código à parte inferior da AppDelegate classe:

[Export("application:openURL:options:")]
public bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
{
    AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(url);
    return true;
}

Adicione acesso às chaves ao Entitlements.plist:

  1. Abra o arquivo Entitlements.plist .

  2. Selecione Chaves.

  3. Selecione Adicionar Novo nos grupos de chaves.

  4. Digite com.microsoft.adalcache como o valor:

    Screenshot showing the i O S entitlements.

Adicione os direitos personalizados ao projeto:

  1. Clique com o botão direito do TodoApp.iOS mouse no projeto e selecione Propriedades.

  2. Selecione Assinatura de pacote do iOS.

  3. Selecione o botão ... ao lado do campo Direitos Personalizados .

  4. Selecione Entitlementse, em seguida, selecione Abrir.

  5. Pressione Ctrl+S para salvar o projeto.

    Screenshot showing the i O S bundle signing properties.

Testar o aplicativo

Observação

Como o aplicativo iOS requer acesso às chaves, você precisará configurar um perfil de provisionamento. Um perfil de provisionamento requer um dispositivo real ou uma conta de desenvolvedor Apple paga (se estiver usando o simulador).

Defina TodoApp.iOS como o projeto de inicialização e, em seguida, compile e execute o aplicativo. Quando o aplicativo for iniciado, você será solicitado a entrar no aplicativo. Na primeira execução, você é solicitado a consentir com o aplicativo. Quando a autenticação estiver concluída, o aplicativo será executado normalmente.

Próximas etapas

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

Leitura adicional