Aggiungere l'autenticazione all'app Xamarin.iOS

In questa esercitazione si aggiunge l'autenticazione Microsoft al progetto TodoApp usando Microsoft Entra ID. Prima di completare questa esercitazione, assicurarsi di aver creato il progetto e distribuito il back-end.

Nota

Poiché l'app iOS richiede l'accesso keychain, è necessario configurare un profilo di provisioning iOS. Un profilo di provisioning richiede un dispositivo iOS reale o un account Apple Developer a pagamento (se si usa il simulatore). È possibile ignorare questa esercitazione e passare all'aggiunta dell'accesso offline all'app se non è possibile usare l'autenticazione a causa di questa restrizione.

Suggerimento

Anche se si usa Microsoft Entra ID per l'autenticazione, è possibile usare qualsiasi libreria di autenticazione desiderata con App per dispositivi mobili di Azure.

Aggiungere l'autenticazione al servizio back-end

Il servizio back-end è un servizio standard ASP.NET 6. Qualsiasi esercitazione che illustra come abilitare l'autenticazione per un servizio ASP.NET 6 funziona con App per dispositivi mobili di Azure.

Per abilitare l'autenticazione di Microsoft Entra per il servizio back-end, è necessario:

  • Registrare un'applicazione con Microsoft Entra ID.
  • Aggiungere il controllo dell'autenticazione al progetto back-end ASP.NET 6.

Registrare l'applicazione

Prima di tutto, registrare l'API Web nel tenant di Microsoft Entra e aggiungere un ambito seguendo questa procedura:

  1. Accedi al portale di Azure.

  2. Se si ha accesso a più tenant, usare il filtro Directory e sottoscrizioni nel menu in alto per passare al tenant in cui si vuole registrare l'applicazione.

  3. Cercare e selezionare Microsoft Entra ID.

  4. In Gestisci selezionare Registrazioni app>Nuova registrazione.

    • Nome: immettere un nome per l'applicazione, ad esempio TodoApp Quickstart. Gli utenti dell'app vedranno questo nome. Puoi modificarlo in un secondo momento.
    • Tipi di account supportati: account in qualsiasi directory organizzativa (qualsiasi directory Di Microsoft Entra - Multi-tenant) e account Microsoft personali (ad esempio Skype, Xbox)
  5. Selezionare Registra.

  6. In Gestisci selezionare Esporre un'API>Aggiungi un ambito.

  7. Per URI ID applicazione accettare l'impostazione predefinita selezionando Salva e continua.

  8. Immetti i dettagli seguenti:

    • Nome ambito: access_as_user
    • Chi può fornire il consenso?: Amministrazione e utenti
    • Nome visualizzato per il consenso amministratore: Access TodoApp
    • Descrizione del consenso amministratore: Allows the app to access TodoApp as the signed-in user.
    • Nome visualizzato per il consenso utente: Access TodoApp
    • Descrizione del consenso utente: Allow the app to access TodoApp on your behalf.
    • Stato: abilitato
  9. Selezionare Aggiungi ambito per completare l'aggiunta dell'ambito.

  10. Si noti il valore dell'ambito, simile a api://<client-id>/access_as_user(definito ambito API Web). È necessario l'ambito durante la configurazione del client.

  11. Selezionare Panoramica.

  12. Prendere nota dell'ID applicazione (client) nella sezione Informazioni di base (denominata ID applicazione API Web). Questo valore è necessario per configurare il servizio back-end.

Aprire Visual Studio e selezionare il TodoAppService.NET6 progetto.

  1. Fare clic con il pulsante destro del TodoAppService.NET6 mouse sul progetto, quindi scegliere Gestisci pacchetti NuGet.

  2. Nella nuova scheda selezionare Sfoglia, quindi immettere Microsoft.Identity.Web nella casella di ricerca.

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

  3. Selezionare il Microsoft.Identity.Web pacchetto e quindi premere Installa.

  4. Seguire le istruzioni per completare l'installazione del pacchetto.

  5. Program.cs aperti. Aggiungere quanto segue all'elenco di using istruzioni:

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
  1. Aggiungere il codice seguente direttamente sopra la chiamata a builder.Services.AddDbContext():
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
  .AddMicrosoftIdentityWebApi(builder.Configuration);
builder.Services.AddAuthorization();
  1. Aggiungere il codice seguente direttamente sopra la chiamata a app.MapControllers():
app.UseAuthentication();
app.UseAuthorization();

Il file Program.cs avrà un aspetto simile al seguente:

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. Modificare l'oggetto Controllers\TodoItemController.cs. Aggiungere un [Authorize] attributo alla classe . La classe dovrebbe essere simile alla seguente:
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. Modificare l'oggetto appsettings.json. Aggiungere il blocco seguente:
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com",
    "ClientId": "<client-id>",
    "TenantId": "common"
  },

<client-id> Sostituire con l'ID applicazione API Web registrato in precedenza. Al termine, dovrebbe essere simile al seguente:

{
  "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": "*"
}

Pubblicare di nuovo il servizio in Azure:

  1. Fare clic con il pulsante destro del mouse sul TodoAppService.NET6 progetto, quindi scegliere Pubblica.
  2. Selezionare il pulsante Pubblica nell'angolo superiore destro della scheda.

Aprire una finestra in https://yoursite.azurewebsites.net/tables/todoitem?ZUMO-API-VERSION=3.0.0. Si noti che il servizio restituisce ora una 401 risposta, che indica che è necessaria l'autenticazione.

Screenshot of the browser showing an error.

Registrare l'app con il servizio di gestione delle identità

Microsoft Data Sync Framework include il supporto predefinito per qualsiasi provider di autenticazione che usa un token Json Web (JWT) all'interno di un'intestazione della transazione HTTP. Questa applicazione usa Microsoft Authentication Library (MSAL) per richiedere tale token e autorizzare l'utente connesso al servizio back-end.

Configurare un'applicazione client nativa

È possibile registrare client nativi per consentire l'autenticazione alle API Web ospitate nell'app usando una libreria client, ad esempio Microsoft Identity Library (MSAL).

  1. Nella portale di Azure selezionare Microsoft Entra ID> Registrazioni app> Nuova registrazione.

  2. Nella pagina Registra un'applicazione :

    • immettere un nome per la registrazione dell'app. È possibile usare il nome native-quickstart per distinguerne uno da quello usato dal servizio back-end.
    • Selezionare Account in qualsiasi directory organizzativa (qualsiasi directory Di Microsoft Entra - Multi-tenant) e account Microsoft personali (ad esempio Skype, Xbox).
    • In URI di reindirizzamento:
      • Selezionare Client pubblico (mobile e desktop)
      • Immettere l'URL quickstart://auth
  3. Selezionare Registra.

  4. Selezionare Autorizzazioni API>Aggiungi un'autorizzazione>Le mie API.

  5. Selezionare la registrazione dell'app creata in precedenza per il servizio back-end. Se la registrazione dell'app non viene visualizzata, assicurarsi di aver aggiunto l'ambito access_as_user .

    Screenshot of the scope registration in the Azure portal.

  6. In Seleziona autorizzazioni selezionare access_as_user e quindi selezionare Aggiungi autorizzazioni.

  7. Selezionare Authentication Mobile and desktop applications (Autenticazione>per dispositivi mobili e applicazioni desktop).

  8. Selezionare la casella accanto a https://login.microsoftonline.com/common/oauth2/nativeclient.

  9. Selezionare la casella accanto a msal{client-id}://auth (sostituendo {client-id} con l'ID applicazione).

  10. Selezionare Aggiungi URI, quindi aggiungere http://localhost nel campo per URI aggiuntivi.

  11. Selezionare Salva nella parte inferiore della pagina.

  12. Selezionare Panoramica. Prendere nota dell'ID applicazione (client) (denominato ID applicazione client nativa) perché è necessario per configurare l'app per dispositivi mobili.

Sono stati definiti tre URL di reindirizzamento:

  • http://localhost viene usato dalle applicazioni WPF.
  • https://login.microsoftonline.com/common/oauth2/nativeclient viene usato dalle applicazioni UWP.
  • msal{client-id}://auth viene usato dalle applicazioni per dispositivi mobili (Android e iOS).

Aggiungere Microsoft Identity Client all'app

Aprire la TodoApp.sln soluzione in Visual Studio e impostare il TodoApp.iOS progetto come progetto di avvio. Aggiungere Microsoft Identity Library (MSAL) al TodoApp.iOS progetto:

Aggiungere Microsoft Identity Library (MSAL) al progetto della piattaforma:

  1. Fare clic con il pulsante destro del mouse sul progetto, quindi scegliere Gestisci pacchetti NuGet.

  2. Selezionare la scheda Sfoglia.

  3. Immettere Microsoft.Identity.Client nella casella di ricerca, quindi premere INVIO.

  4. Selezionare il Microsoft.Identity.Client risultato, quindi fare clic su Installa.

    Screenshot of selecting the MSAL NuGet in Visual Studio.

  5. Accettare il contratto di licenza per continuare l'installazione.

Aggiungere l'ID client nativo e l'ambito back-end alla configurazione.

Aprire il TodoApp.Data progetto e modificare il Constants.cs file. Aggiungere costanti per 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>"
      };
  }

<client-id> Sostituire con l'ID applicazione Native Client ricevuto durante la registrazione dell'applicazione client in MICROSOFT Entra ID e <scope> con l'ambito API Web copiato quando si usa Esporre un'API durante la registrazione dell'applicazione di servizio.

Aprire ViewControllers\HomeViewController.cs nel TodoApp.iOS progetto. Aggiungere le istruzioni using seguenti:

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

HomeViewController Nella classe aggiungere una nuova proprietà:

public IPublicClientApplication IdentityClient { get; set; }

Modificare il costruttore per leggere:

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

Aggiungere il GetAuthenticationToken metodo alla 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 ?? ""
    };
}

Il GetAuthenticationToken() metodo funziona con Microsoft Identity Library (MSAL) per ottenere un token di accesso adatto per autorizzare l'utente connesso al servizio back-end. Questa funzione viene quindi passata a RemoteTodoService per la creazione del client. Se l'autenticazione ha esito positivo, viene AuthenticationToken generato con i dati necessari per autorizzare ogni richiesta. In caso contrario, viene generato un token non valido scaduto.

Aggiungere il codice seguente alla fine della AppDelegate classe :

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

Aggiungere l'accesso Entitlements.plistkeychain a :

  1. Apri il file Entitlements.plist.

  2. Selezionare Portachiavi.

  3. Selezionare Aggiungi nuovo nei gruppi keychain.

  4. Immettere com.microsoft.adalcache come valore:

    Screenshot showing the i O S entitlements.

Aggiungere i diritti personalizzati al progetto:

  1. Fare clic con il pulsante destro del mouse sul TodoApp.iOS progetto, quindi scegliere Proprietà.

  2. Selezionare Firma bundle iOS.

  3. Selezionare il pulsante ... accanto al campo Diritti personalizzati.

  4. Selezionare Entitlementse quindi Apri.

  5. Premere CTRL+S per salvare il progetto.

    Screenshot showing the i O S bundle signing properties.

Testare l'app

Nota

Poiché l'app iOS richiede l'accesso keychain, è necessario configurare un profilo di provisioning. Un profilo di provisioning richiede un dispositivo reale o un account Apple Developer a pagamento (se si usa il simulatore).

Impostare TodoApp.iOS come progetto di avvio, quindi compilare ed eseguire l'app. All'avvio dell'app viene richiesto di accedere all'app. Alla prima esecuzione viene chiesto di fornire il consenso all'app. Al termine dell'autenticazione, l'app viene eseguita normalmente.

Passaggi successivi

Configurare quindi l'applicazione in modo che funzioni offline implementando un archivio offline.

Altre risorse