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:
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.
Cercare e selezionare ID Microsoft Entra.
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)
Selezionare Registra.
In Gestisciselezionare Esporre un'API>Aggiungere un ambito.
Per URI ID applicazione, accettare l'impostazione predefinita selezionando Salva e continua.
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
-
nome ambito:
Selezionare Aggiungi ambito per completare l'aggiunta dell'ambito.
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.Selezionare Panoramica.
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
.
Fare clic con il pulsante destro del mouse sul progetto
TodoAppService.NET6
, quindi selezionare Gestisci pacchetti NuGet....Nella nuova scheda selezionare Sfoglia, quindi immettere Microsoft.Identity.Web nella casella di ricerca.
Selezionare il pacchetto di
Microsoft.Identity.Web
, quindi premere Installa.Seguire le istruzioni per completare l'installazione del pacchetto.
Aprire
Program.cs
. Aggiungere quanto segue all'elenco di istruzioniusing
:
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
- Aggiungere il codice seguente direttamente sopra la chiamata a
builder.Services.AddDbContext()
:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration);
builder.Services.AddAuthorization();
- 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();
- 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))
{
}
}
}
- 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:
- Fare clic con il pulsante destro del mouse sul progetto di
TodoAppService.NET6
, quindi selezionare Pubblica.... - 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.
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
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).
Nel portale di Azure selezionare ID Microsoft Entra>Registrazioni app>Nuova registrazione.
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
- immettere un Nome per la registrazione dell'app. È possibile usare il nome
Selezionare Registra.
Selezionare autorizzazioni API >Aggiungere un'autorizzazione>API personali.
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.
In Selezionare le autorizzazioniselezionare access_as_usere quindi selezionare Aggiungi autorizzazioni.
Selezionare Autenticazione>applicazioni per dispositivi mobili e desktop.
Selezionare la casella accanto a
https://login.microsoftonline.com/common/oauth2/nativeclient
.Selezionare la casella accanto a
msal{client-id}://auth
(sostituendo{client-id}
con l'ID applicazione).Selezionare Aggiungi URI, quindi aggiungere
http://localhost
nel campo per URI aggiuntivi.Selezionare Salva nella parte inferiore della pagina.
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)
Aggiungere il
Fare clic con il pulsante destro del mouse sul progetto, quindi selezionare Gestisci pacchetti NuGet....
Selezionare la scheda sfoglia
. Immettere
Microsoft.Identity.Client
nella casella di ricerca, quindi premere INVIO.Selezionare il risultato
Microsoft.Identity.Client
, quindi fare clic su Installa.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.