Adicionar autenticação à sua aplicação Xamarin.iOS

Neste tutorial, você adiciona 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 o back-end.

Nota

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 adicionar acesso offline ao seu aplicativo se não puder usar a autenticação devido a essa restrição.

Gorjeta

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 do 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:

  • Registe uma aplicação com o Microsoft Entra ID.
  • Adicione a verificação de autenticação ao projeto de back-end do ASP.NET 6.

Registar a candidatura

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

  1. Inicie sessão 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. Procure e selecione Microsoft Entra ID.

  4. Em Gerir, selecione Registos de>aplicações Novo registo.

    • Nome: insira um nome para o seu aplicativo, por exemplo, TodoApp Quickstart. Os usuários do seu aplicativo verão esse nome. Você pode alterá-lo mais tarde.
    • Tipos de conta suportados: Contas em qualquer diretório organizacional (Qualquer diretório Microsoft Entra - Multilocatário) e contas pessoais da Microsoft (por exemplo, Skype, Xbox)
  5. Selecione Registar.

  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. Introduza os detalhes seguintes:

    • Nome do escopo: access_as_user
    • Quem pode consentir?: Administradores e utilizadores
    • Nome de exibição do 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 utilizador: Allow the app to access TodoApp on your behalf.
    • Estado: Ativado
  9. Selecione Adicionar escopo para concluir a adição de escopo.

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

  11. Selecione Descrição geral.

  12. Observe a ID do Aplicativo (cliente) na seção Essentials (conhecida como 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 TodoAppService.NET6 projeto.

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

  2. No novo separador, selecione Procurar e, em seguida, introduza 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. Abrir 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();

O seu Program.cs deverá ter um aspeto semelhante a:

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 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.jsonarquivo . Adicione o seguinte bloco:
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com",
    "ClientId": "<client-id>",
    "TenantId": "common"
  },

Substitua o <client-id> pelo ID do aplicativo da API Web que você registrou anteriormente. Uma vez concluído, deve 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 rato no TodoAppService.NET6 projeto e, em seguida, 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, o 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 usa um Json Web Token (JWT) dentro de 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 cliente nativo

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

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

  2. Na página Registar uma candidatura:

    • 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 Microsoft Entra - Multilocatário) e contas pessoais da Microsoft (por exemplo, Skype, Xbox).
    • No URI de redirecionamento:
      • Selecione Cliente público (móvel ou desktop)
      • Insira o URL quickstart://auth
  3. Selecione Registar.

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

  5. Selecione o registro do aplicativo que você criou anteriormente para seu serviço de back-end. Se não vir o registo da aplicação, certifique-se de que adicionou o âmbito 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} pelo ID do aplicativo).

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

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

  12. Selecione Descrição geral. Anote o ID do Aplicativo (cliente) (conhecido 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 é utilizado por aplicações 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 o Microsoft Identity Library (MSAL) ao TodoApp.iOS projeto:

Adicione o 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 o separador Procurar.

  3. Introduza Microsoft.Identity.Client na caixa de pesquisa e, em seguida, prima Enter.

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

    Screenshot of selecting the MSAL NuGet in Visual Studio.

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

Adicione o ID do cliente nativo e o escopo do 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 com o ID do Aplicativo Cliente Nativo que você recebeu ao registrar o aplicativo cliente no ID do Microsoft Entra e o com o Escopo da API Web que você copiou quando usou Expor uma API ao registrar o <client-id><scope>aplicativo de serviço.

Aberto ViewControllers\HomeViewController.cs no TodoApp.iOS projeto. Adicione as seguintes instruções 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 GetAuthenticationToken método à 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. Esta função é então passada para o para a RemoteTodoService criação do cliente. Se a autenticação for bem-sucedida, a é produzida com os AuthenticationToken dados necessários para autorizar cada solicitação. Se não, então um token incorreto expirado é produzido em vez disso.

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 ficheiro Entitlements.plist.

  2. Selecione Porta-chaves.

  3. Selecione Adicionar Novo nos grupos de chaves.

  4. Insira 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 iOS Bundle Signing.

  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 a aplicação

Nota

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, crie e execute o aplicativo. Quando a aplicação é iniciada, é-lhe pedido para iniciar sessão na aplicação. Na primeira execução, você será solicitado a consentir com o aplicativo. Quando a autenticação estiver concluída, o aplicativo será executado normalmente.

Próximos passos

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

Leitura adicional