Xamarin.Essentials: Web Authenticator

La classe WebAuthenticator consente di avviare flussi basati su browser in ascolto di un callback a un URL specifico registrato nell'app.

Panoramica

Molte app richiedono l'aggiunta dell'autenticazione utente e questo spesso significa consentire agli utenti di accedere ai propri account Microsoft, Facebook, Google e ora Apple Sign In.

Microsoft Authentication Library (MSAL) offre un'eccellente soluzione turn-key per aggiungere l'autenticazione all'app. È anche disponibile il supporto per le app Xamarin nel pacchetto NuGet client.

Se si è interessati a usare il proprio servizio Web per l'autenticazione, è possibile usare WebAuthenticator per implementare la funzionalità lato client.

Perché usare un back-end del server?

Molti provider di autenticazione sono stati spostati nell'offerta solo di flussi di autenticazione espliciti o a due zampe per garantire una maggiore sicurezza. Ciò significa che è necessario un segreto client dal provider per completare il flusso di autenticazione. Sfortunatamente, le app per dispositivi mobili non sono un ottimo punto in cui archiviare i segreti e qualsiasi elemento archiviato nel codice, nei file binari di un'app per dispositivi mobili o in genere è considerato non sicuro.

La procedura consigliata consiste nell'usare un back-end Web come livello intermedio tra l'app per dispositivi mobili e il provider di autenticazione.

Importante

È consigliabile evitare l'uso di librerie e modelli di autenticazione di solo dispositivi mobili meno recenti che non sfruttano un back-end Web nel flusso di autenticazione a causa della mancanza intrinseca di sicurezza per l'archiviazione dei segreti client.

Operazioni preliminari

Per iniziare a usare questa API, leggere la guida introduttiva per Xamarin.Essentials assicurarsi che la libreria sia installata e configurata correttamente nei progetti.

Per accedere alla funzionalità WebAuthenticator è necessaria la configurazione specifica della piattaforma seguente.

Android richiede una configurazione filtro finalità per gestire l'URI di callback. Questa operazione viene eseguita facilmente sottoclassando la WebAuthenticatorCallbackActivity classe :

const string CALLBACK_SCHEME = "myapp";

[Activity(NoHistory = true, LaunchMode = LaunchMode.SingleTop, Exported = true)]
[IntentFilter(new[] { Android.Content.Intent.ActionView },
    Categories = new[] { Android.Content.Intent.CategoryDefault, Android.Content.Intent.CategoryBrowsable },
    DataScheme = CALLBACK_SCHEME)]
public class WebAuthenticationCallbackActivity : Xamarin.Essentials.WebAuthenticatorCallbackActivity
{
}

Se la versione di Android di destinazione del progetto è impostata su Android 11 (API R 30) è necessario aggiornare il manifesto Android con query usate con i nuovi requisiti di visibilità del pacchetto.

Aprire il file AndroidManifest.xml nella cartella Proprietà e aggiungere quanto segue all'interno del nodo manifesto:

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

Uso di WebAuthenticator

Aggiungere un riferimento a Xamarin.Essentials nella classe :

using Xamarin.Essentials;

L'API è costituita principalmente da un singolo metodo AuthenticateAsync che accetta due parametri: l'URL che deve essere usato per avviare il flusso del Web browser e l'URI a cui si prevede che il flusso venga richiamato e a cui l'app è registrata per poter gestire.

Il risultato è un oggetto WebAuthenticatorResult che include tutti i parametri di query analizzati dall'URI di callback:

var authResult = await WebAuthenticator.AuthenticateAsync(
        new Uri("https://mysite.com/mobileauth/Microsoft"),
        new Uri("myapp://"));

var accessToken = authResult?.AccessToken;

L'API WebAuthenticator si occupa dell'avvio dell'URL nel browser e dell'attesa fino alla ricezione del callback:

Typical Web Authentication Flow

Se l'utente annulla il flusso in qualsiasi momento, viene generata un'eccezione TaskCanceledException .

Sessione di autenticazione privata

iOS 13 ha introdotto un'API del Web browser temporanea per gli sviluppatori per avviare la sessione di autenticazione come privata. Ciò consente agli sviluppatori di richiedere che non siano disponibili cookie condivisi o dati di esplorazione tra le sessioni di autenticazione e sarà una nuova sessione di accesso ogni volta. Questa funzionalità è disponibile tramite il nuovo WebAuthenticatorOptions introdotto nella Xamarin.Essentials versione 1.7 per iOS.

var url = new Uri("https://mysite.com/mobileauth/Microsoft");
var callbackUrl = new Uri("myapp://");
var authResult = await WebAuthenticator.AuthenticateAsync(new WebAuthenticatorOptions
    {
        Url = url,
        CallbackUrl = callbackUrl,
        PrefersEphemeralWebBrowserSession = true
    });

Differenze tra le piattaforme

Le schede personalizzate vengono usate ogni volta che è disponibile; in caso contrario, viene avviata una finalità per l'URL.

Accesso Apple

Secondo le linee guida di revisione di Apple, se l'app usa un servizio di accesso social per l'autenticazione, deve anche offrire Apple Sign In come opzione.

Per aggiungere Apple Sign In alle app, è prima necessario configurare l'app per l'uso dell'accesso Apple.

Per iOS 13 e versioni successive è consigliabile chiamare il AppleSignInAuthenticator.AuthenticateAsync() metodo . In questo modo si userà l'API di accesso Di Apple nativa, in modo che gli utenti ottengano la migliore esperienza possibile su questi dispositivi. È possibile scrivere il codice condiviso per usare l'API corretta in fase di esecuzione come segue:

var scheme = "..."; // Apple, Microsoft, Google, Facebook, etc.
WebAuthenticatorResult r = null;

if (scheme.Equals("Apple")
    && DeviceInfo.Platform == DevicePlatform.iOS
    && DeviceInfo.Version.Major >= 13)
{
    // Use Native Apple Sign In API's
    r = await AppleSignInAuthenticator.AuthenticateAsync();
}
else
{
    // Web Authentication flow
    var authUrl = new Uri(authenticationUrl + scheme);
    var callbackUrl = new Uri("xamarinessentials://");

    r = await WebAuthenticator.AuthenticateAsync(authUrl, callbackUrl);
}

var authToken = string.Empty;
if (r.Properties.TryGetValue("name", out var name) && !string.IsNullOrEmpty(name))
    authToken += $"Name: {name}{Environment.NewLine}";
if (r.Properties.TryGetValue("email", out var email) && !string.IsNullOrEmpty(email))
    authToken += $"Email: {email}{Environment.NewLine}";

// Note that Apple Sign In has an IdToken and not an AccessToken
authToken += r?.AccessToken ?? r?.IdToken;

Suggerimento

Per i dispositivi non iOS 13 verrà avviato il flusso di autenticazione Web, che può essere usato anche per abilitare l'accesso Apple nei dispositivi Android e UWP. È possibile accedere all'account iCloud nel simulatore iOS per testare l'accesso ad Apple.


back-end del server principale ASP.NET

È possibile usare l'API WebAuthenticator con qualsiasi servizio back-end Web. Per usarla con un'app principale ASP.NET, è prima necessario configurare l'app Web con la procedura seguente:

  1. Configurare i provider di autenticazione social esterni desiderati in un'app Web ASP.NET Core.
  2. Impostare lo schema di autenticazione predefinito su CookieAuthenticationDefaults.AuthenticationScheme nella .AddAuthentication() chiamata.
  3. Usare .AddCookie() nella chiamata Startup.cs .AddAuthentication() .
  4. Tutti i provider devono essere configurati con .SaveTokens = true;.
services.AddAuthentication(o =>
    {
        o.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    })
    .AddCookie()
    .AddFacebook(fb =>
    {
        fb.AppId = Configuration["FacebookAppId"];
        fb.AppSecret = Configuration["FacebookAppSecret"];
        fb.SaveTokens = true;
    });

Suggerimento

Se si vuole includere Apple Sign In, è possibile usare il AspNet.Security.OAuth.Apple pacchetto NuGet. È possibile visualizzare l'esempio di Startup.cs completo nel repository GitHub essentials.

Aggiungere un controller di autenticazione per dispositivi mobili personalizzato

Con un flusso di autenticazione per dispositivi mobili è in genere consigliabile avviare il flusso direttamente a un provider scelto dall'utente( ad esempio facendo clic su un pulsante "Microsoft" nella schermata di accesso dell'app). È anche importante essere in grado di restituire informazioni pertinenti all'app in un URI di callback specifico per terminare il flusso di autenticazione.

A tale scopo, usare un controller API personalizzato:

[Route("mobileauth")]
[ApiController]
public class AuthController : ControllerBase
{
    const string callbackScheme = "myapp";

    [HttpGet("{scheme}")] // eg: Microsoft, Facebook, Apple, etc
    public async Task Get([FromRoute]string scheme)
    {
        // 1. Initiate authentication flow with the scheme (provider)
        // 2. When the provider calls back to this URL
        //    a. Parse out the result
        //    b. Build the app callback URL
        //    c. Redirect back to the app
    }
}

Lo scopo di questo controller è dedurre lo schema (provider) richiesto dall'app e avviare il flusso di autenticazione con il provider di social networking. Quando il provider esegue il callback al back-end Web, il controller analizza il risultato e reindirizza all'URI di callback dell'app con parametri.

A volte può essere necessario restituire dati, ad esempio il provider, access_token all'app che è possibile eseguire tramite i parametri di query dell'URI di callback. In alternativa, è possibile creare una propria identità nel server e passare il proprio token all'app. Che cosa e come si fa questa parte è per voi!

Vedere l'esempio completo del controller nel repository Essentials.

Nota

L'esempio precedente illustra come restituire il token di accesso dal provider di autenticazione di terze parti (ie: OAuth). Per ottenere un token che è possibile usare per autorizzare le richieste Web al back-end Web stesso, è necessario creare il proprio token nell'app Web e restituirlo. La panoramica dell'autenticazione ASP.NET Core contiene altre informazioni sugli scenari di autenticazione avanzati in ASP.NET Core.


API