Condividi tramite


Aggiungere l'autenticazione all'app Xamarin.Android

Nota

Questo prodotto viene ritirato. Per una sostituzione dei progetti che usano .NET 8 o versione successiva, vedere la libreria datasync di Community Toolkit.

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.

Mancia

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. Accedere 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 ID Microsoft Entra.

  4. In Gestisciselezionare Registrazioni app>Nuova registrazione.

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

  6. In Gestisciselezionare Esporre un'API>Aggiungere un ambito.

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

  8. Immettere i dettagli seguenti:

    • nome ambito: access_as_user
    • Chi può fornire il consenso?: amministratori e utenti
    • nome visualizzato del consenso amministratore: Access TodoApp
    • Descrizione del consenso amministratore : Allows the app to access TodoApp as the signed-in user.
    • Nome visualizzato del consenso utente: Access TodoApp
    • Descrizione del consenso utente: Allow the app to access TodoApp on your behalf.
    • State: Enabled
  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 (detto ambito API Web ). È necessario l'ambito durante la configurazione del client.

  11. Selezionare Panoramica.

  12. Si noti l'ID applicazione (client) nella sezione Essentials (id applicazione API Web ). Questo valore è necessario per configurare il servizio back-end.

Aprire Visual Studio e selezionare il progetto TodoAppService.NET6.

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

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

    Screenshot dell'aggiunta di M S A L NuGet in Visual Studio.

  3. Selezionare il pacchetto di Microsoft.Identity.Web, quindi premere Installa.

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

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

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

Sostituire il <client-id> 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 progetto di TodoAppService.NET6, quindi selezionare Pubblica....
  2. Selezionare il pulsante Pubblica nell'angolo superiore destro della scheda.

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

Screenshot del browser che mostra un errore.

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 il 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. Nel portale di Azure selezionare ID Microsoft Entra>Registrazioni app>Nuova registrazione.

  2. Nella pagina Registrare 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 Microsoft Entra - Multi-tenant) e account Microsoft personali (ad esempio Skype, Xbox).
    • In URI di reindirizzamento:
      • Selezionare client pubblico (desktop & per dispositivi mobili)
      • Immettere l'URL quickstart://auth
  3. Selezionare Registra.

  4. Selezionare autorizzazioni API >Aggiungere un'autorizzazione>API personali.

  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 della registrazione dell'ambito nel portale di Azure.

  6. In Selezionare le autorizzazioniselezionare access_as_usere quindi selezionare Aggiungi autorizzazioni.

  7. Selezionare Autenticazione>applicazioni per dispositivi mobili e 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 del ID applicazione (client) (detto ID applicazione client native client) perché è necessario 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 soluzione TodoApp.sln in Visual Studio e impostare il progetto TodoApp.Android come progetto di avvio. Aggiungere il di Microsoft Identity Library (MSAL) al progetto di :

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

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

  2. Selezionare la scheda sfoglia .

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

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

    Screenshot della selezione di 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 progetto TodoApp.Data e modificare il file di Constants.cs. 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>"
      };
  }

Sostituire il <client-id> con l'ID applicazione native ricevuta durante la registrazione dell'applicazione client in Microsoft Entra ID e l'<scope> con l'ambito api Web copiato quando è stato usato Esporre un API durante la registrazione dell'applicazione di servizio.

Aprire il file MainActivity.cs nel progetto TodoApp.Android. Nella parte superiore del file aggiungere le istruzioni using seguenti:

using Android.Content;
using Microsoft.Identity.Client;
using Microsoft.Datasync.Client;
using System.Linq;
using System.Threading.Tasks;
using Debug = System.Diagnostics.Debug;

Nella parte superiore della classe MainActivity aggiungere il campo seguente:

public IPublicClientApplication identityClient;

Nel metodo OnCreate() modificare la definizione del TodoService:

TodoService = new RemoteTodoService(GetAuthenticationToken);

Aggiungere il codice seguente per definire il metodo GetAuthenticationToken():

public async Task<AuthenticationToken> GetAuthenticationToken()
{
    if (identityClient == null)
    {
        identityClient = PublicClientApplicationBuilder.Create(Constants.ApplicationId)
            .WithAuthority(AzureCloudInstance.AzurePublic, "common")
            .WithRedirectUri($"msal{Constants.ApplicationId}://auth")
            .WithParentActivityOrWindow(() => this)
            .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 metodo GetAuthenticationToken() 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 al RemoteTodoService per la creazione del client. Se l'autenticazione ha esito positivo, il AuthenticationToken viene generato con i dati necessari per autorizzare ogni richiesta. In caso contrario, viene generato un token non valido scaduto.

Gestire il callback dal client identity aggiungendo il metodo seguente:

protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
{
    base.OnActivityResult(requestCode, resultCode, data);
    // Return control to MSAL
    AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(requestCode, resultCode, data);
}

Creare una nuova classe MsalActivity con il codice seguente:

using Android.App;
using Android.Content;
using Microsoft.Identity.Client;

namespace TodoApp.Android
{
    [Activity(Exported = true)]
    [IntentFilter(new[] { Intent.ActionView },
        Categories = new[] { Intent.CategoryBrowsable, Intent.CategoryDefault },
        DataHost = "auth",
        DataScheme = "msal{client-id}")]
    public class MsalActivity : BrowserTabActivity
    {
    }
}

Sostituire {client-id} con l'ID applicazione del client nativo (uguale a Constants.ApplicationId).

Se il progetto è destinato a Android versione 11 (API versione 30) o successiva, è necessario aggiornare il AndroidManifest.xml per soddisfare i requisiti di visibilità dei pacchetti Android . Aprire Properties/AndroidManifest.xml e aggiungere i nodi di queries/intent seguenti al nodo manifest:

<manifest>
  ...
  <queries>
    <intent>
      <action android:name="android.support.customtabs.action.CustomTabsService" />
    </intent>
  </queries>
</manifest>

Testare l'app

Eseguire o riavviare l'app.

Quando l'app viene eseguita, viene aperto un browser per richiedere l'autenticazione. Se non è stata eseguita l'autenticazione con l'app in precedenza, l'app chiede di fornire il consenso. Al termine dell'autenticazione, il browser di sistema si chiude e l'app viene eseguita come prima.

Passaggi successivi

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

Altre informazioni