Autenticare gli utenti con Azure Active Directory B2C

Azure Active Directory B2C offre la gestione delle identità cloud per applicazioni Web e per dispositivi mobili rivolte agli utenti. Questo articolo illustra come usare Azure Active Directory B2C per integrare la gestione delle identità in un'applicazione per dispositivi mobili con Microsoft Authentication Library.

Panoramica

Azure Active Directory B2C (ADB2C) è un servizio di gestione delle identità per le applicazioni rivolte agli utenti. Consente agli utenti di accedere all'applicazione usando gli account di social networking esistenti o credenziali personalizzate, ad esempio indirizzo di posta elettronica o nome utente e password. Gli account di credenziali personalizzati vengono definiti account locali .

Il processo di integrazione del servizio di gestione delle identità B2C di Azure Active Directory in un'applicazione per dispositivi mobili è il seguente:

  1. Creare un tenant di Azure Active Directory B2C.
  2. Registrare l'applicazione per dispositivi mobili con il tenant di Azure Active Directory B2C.
  3. Creare criteri per l'iscrizione e l'accesso e i flussi utente password dimenticati.
  4. Usare Microsoft Authentication Library (MSAL) per avviare un flusso di lavoro di autenticazione con il tenant di Azure Active Directory B2C.

Nota

Se non si ha una sottoscrizione di Azure, creare un account gratuito prima di iniziare.

Azure Active Directory B2C supporta più provider di identità, tra cui Microsoft, GitHub, Facebook, Twitter e altro ancora. Per altre informazioni sulle funzionalità di Azure Active Directory B2C, vedere documentazione di Azure Active Directory B2C.

Microsoft Authentication Library supporta più architetture di applicazioni e piattaforme. Per informazioni sulle funzionalità MSAL, vedere Microsoft Authentication Library su GitHub.

Configurare un tenant di Azure Active Directory B2C

Per eseguire il progetto di esempio, è necessario creare un tenant di Azure Active Directory B2C. Per altre informazioni, vedere Creare un tenant di Azure Active Directory B2C nel portale di Azure.

Dopo aver creato un tenant, è necessario il nome del tenant e l'ID tenant per configurare l'applicazione per dispositivi mobili. L'ID tenant e il nome vengono definiti dal dominio generato al momento della creazione dell'URL del tenant. Se l'URL del tenant generato è https://contoso20190410tenant.onmicrosoft.com/ l'ID tenant e contoso20190410tenant.onmicrosoft.com il nome del tenant è contoso20190410tenant. Trovare il dominio tenant nella portale di Azure facendo clic sul filtro della directory e della sottoscrizione nel menu in alto. Lo screenshot seguente mostra il pulsante di filtro della directory e della sottoscrizione di Azure e il dominio del tenant:

Nome del tenant nella visualizzazione filtro della directory e della sottoscrizione di Azure

Nel progetto di esempio modificare il file Constants.cs per impostare i tenantName campi e tenantId . Il codice seguente mostra come impostare questi valori se il dominio del tenant è https://contoso20190410tenant.onmicrosoft.com/, sostituire questi valori con i valori del portale:

public static class Constants
{
    static readonly string tenantName = "contoso20190410tenant";
    static readonly string tenantId = "contoso20190410tenant.onmicrosoft.com";
    ...
}

Registrare l'applicazione per dispositivi mobili con Azure Active Directory B2C

Prima di poter connettersi e autenticare gli utenti, è necessario registrare un'applicazione per dispositivi mobili con il tenant. Il processo di registrazione assegna un ID applicazione univoco all'applicazione e un URL di reindirizzamento che indirizza le risposte all'applicazione dopo l'autenticazione. Per altre informazioni, vedere Azure Active Directory B2C: Registrare l'applicazione. Sarà necessario conoscere l'ID applicazione assegnato all'applicazione, elencato dopo il nome dell'applicazione nella visualizzazione delle proprietà. Lo screenshot seguente mostra dove trovare l'ID applicazione:

ID applicazione nella visualizzazione delle proprietà dell'applicazione Azure

Microsoft Authentication Library prevede che l'URL di reindirizzamento dell'applicazione sia preceduto dal testo "msal" e seguito da un endpoint denominato "auth". Se l'ID applicazione è "1234abcd", l'URL completo deve essere msal1234abcd://auth. Assicurarsi che l'applicazione abbia abilitato l'impostazione Client nativo e creare un URI di reindirizzamento personalizzato usando l'ID applicazione, come illustrato nello screenshot seguente:

URI di reindirizzamento personalizzato nella visualizzazione delle proprietà dell'applicazione Azure

L'URL verrà usato in un secondo momento sia in Android ApplicationManifest.xml che in iOS Info.plist.

Nel progetto di esempio modificare il file Constants.cs per impostare il clientId campo sull'ID applicazione. Il codice seguente mostra come impostare questo valore se l'ID applicazione è 1234abcd:

public static class Constants
{
    static readonly string tenantName = "contoso20190410tenant";
    static readonly string tenantId = "contoso20190410tenant.onmicrosoft.com";
    static readonly string clientId = "1234abcd";
    ...
}

Creare criteri di iscrizione e accesso e password dimenticati

Un criterio è un'esperienza che gli utenti passano per completare un'attività, ad esempio la creazione di un account o la reimpostazione di una password. Un criterio specifica anche il contenuto dei token ricevuti dall'applicazione quando l'utente restituisce l'esperienza. È necessario configurare i criteri per l'iscrizione e l'accesso dell'account e reimpostare la password. Azure include criteri predefiniti che semplificano la creazione di criteri comuni. Per altre informazioni, vedere Azure Active Directory B2C: Criteri predefiniti.

Dopo aver completato la configurazione dei criteri, è necessario disporre di due criteri nella visualizzazione Flussi utente (criteri) nella portale di Azure. Lo screenshot seguente illustra due criteri configurati nella portale di Azure:

Due criteri configurati nella visualizzazione Flussi utente di Azure (criteri)

Nel progetto di esempio modificare il file Constants.cs per impostare i policySignin campi e policyPassword in modo da riflettere i nomi scelti durante l'installazione dei criteri:

public static class Constants
{
    static readonly string tenantName = "contoso20190410tenant";
    static readonly string tenantId = "contoso20190410tenant.onmicrosoft.com";
    static readonly string clientId = "1234abcd";
    static readonly string policySignin = "B2C_1_signupsignin1";
    static readonly string policyPassword = "B2C_1_passwordreset";
    ...
}

Usare Microsoft Authentication Library (MSAL) per l'autenticazione

Il pacchetto NuGet microsoft Authentication Library (MSAL) deve essere aggiunto al progetto condiviso, .NET Standard e ai progetti di piattaforma in una Xamarin.Forms soluzione. MSAL include una PublicClientApplicationBuilder classe che costruisce un oggetto aderendo all'interfaccia IPublicClientApplication . MSAL usa clausole With per fornire parametri aggiuntivi al costruttore e ai metodi di autenticazione.

Nel progetto di esempio il code behind per App.xaml definisce le proprietà statiche denominate AuthenticationClient e UIParente crea un'istanza dell'oggetto AuthenticationClient nel costruttore. La WithIosKeychainSecurityGroup clausola fornisce un nome di gruppo di sicurezza per le applicazioni iOS. La WithB2CAuthority clausola fornisce l'autorità predefinita o i criteri che verranno usati per autenticare gli utenti. La WithRedirectUri clausola indica all'istanza di Hub di notifica di Azure quale URI di reindirizzamento usare se vengono specificati più URI. Nell'esempio seguente viene illustrato come creare un'istanza di PublicClientApplication:

public partial class App : Application
{
    public static IPublicClientApplication AuthenticationClient { get; private set; }

    public static object UIParent { get; set; } = null;

    public App()
    {
        InitializeComponent();

        AuthenticationClient = PublicClientApplicationBuilder.Create(Constants.ClientId)
            .WithIosKeychainSecurityGroup(Constants.IosKeychainSecurityGroups)
            .WithB2CAuthority(Constants.AuthoritySignin)
            .WithRedirectUri($"msal{Constants.ClientId}://auth")
            .Build();

        MainPage = new NavigationPage(new LoginPage());
    }

    ...

Nota

Se l'istanza di Hub di notifica di Azure dispone di un solo URI di reindirizzamento definito, l'istanza AuthenticationClient può funzionare senza specificare l'URI di reindirizzamento con la WithRedirectUri clausola . Tuttavia, è necessario specificare sempre questo valore nel caso in cui la configurazione di Azure si espande per supportare altri client o metodi di autenticazione.

Il OnAppearing gestore eventi nella LoginPage.xaml.cs code-behind chiama AcquireTokenSilentAsync per aggiornare il token di autenticazione per gli utenti che hanno eseguito l'accesso in precedenza. Il processo di autenticazione viene reindirizzato all'oggetto LogoutPage in caso di esito positivo e non esegue alcuna operazione in caso di errore. L'esempio seguente mostra il processo di riautenticazione invisibile all'utente in OnAppearing:

public partial class LoginPage : ContentPage
{
    ...

    protected override async void OnAppearing()
    {
        try
        {
            // Look for existing account
            IEnumerable<IAccount> accounts = await App.AuthenticationClient.GetAccountsAsync();

            AuthenticationResult result = await App.AuthenticationClient
                .AcquireTokenSilent(Constants.Scopes, accounts.FirstOrDefault())
                .ExecuteAsync();

            await Navigation.PushAsync(new LogoutPage(result));
        }
        catch
        {
            // Do nothing - the user isn't logged in
        }
        base.OnAppearing();
    }

    ...
}

Il OnLoginButtonClicked gestore eventi (attivato quando si fa clic sul pulsante Login) chiama AcquireTokenAsync. La libreria MSAL apre automaticamente il browser del dispositivo mobile e passa alla pagina di accesso. L'URL di accesso, denominato Autorità, è una combinazione del nome e dei criteri del tenant definiti nel file Constants.cs . Se l'utente sceglie l'opzione password dimenticata, viene restituita all'app con un'eccezione, che avvia l'esperienza password dimenticata. L'esempio seguente illustra il processo di autenticazione:

public partial class LoginPage : ContentPage
{
    ...

    async void OnLoginButtonClicked(object sender, EventArgs e)
    {
        AuthenticationResult result;
        try
        {
            result = await App.AuthenticationClient
                .AcquireTokenInteractive(Constants.Scopes)
                .WithPrompt(Prompt.SelectAccount)
                .WithParentActivityOrWindow(App.UIParent)
                .ExecuteAsync();

            await Navigation.PushAsync(new LogoutPage(result));
        }
        catch (MsalException ex)
        {
            if (ex.Message != null && ex.Message.Contains("AADB2C90118"))
            {
                result = await OnForgotPassword();
                await Navigation.PushAsync(new LogoutPage(result));
            }
            else if (ex.ErrorCode != "authentication_canceled")
            {
                await DisplayAlert("An error has occurred", "Exception message: " + ex.Message, "Dismiss");
            }
        }
    }

    ...
}

Il OnForgotPassword metodo è simile al processo di accesso, ma implementa un criterio personalizzato. OnForgotPasswordusa un overload diverso di AcquireTokenAsync, che consente di fornire un'autorità specifica. Nell'esempio seguente viene illustrato come fornire un'autorità personalizzata durante l'acquisizione di un token:

public partial class LoginPage : ContentPage
{
    ...
    async Task<AuthenticationResult> OnForgotPassword()
    {
        try
        {
            return await App.AuthenticationClient
                .AcquireTokenInteractive(Constants.Scopes)
                .WithPrompt(Prompt.SelectAccount)
                .WithParentActivityOrWindow(App.UIParent)
                .WithB2CAuthority(Constants.AuthorityPasswordReset)
                .ExecuteAsync();
        }
        catch (MsalException)
        {
            // Do nothing - ErrorCode will be displayed in OnLoginButtonClicked
            return null;
        }
    }
}

La parte finale dell'autenticazione è il processo di disconnesso. Il OnLogoutButtonClicked metodo viene chiamato quando l'utente preme il pulsante di disconnessione. Esegue un ciclo in tutti gli account e garantisce che i token siano stati invalidati. L'esempio seguente illustra l'implementazione della disconnessa:

public partial class LogoutPage : ContentPage
{
    ...
    async void OnLogoutButtonClicked(object sender, EventArgs e)
    {
        IEnumerable<IAccount> accounts = await App.AuthenticationClient.GetAccountsAsync();

        while (accounts.Any())
        {
            await App.AuthenticationClient.RemoveAsync(accounts.First());
            accounts = await App.AuthenticationClient.GetAccountsAsync();
        }

        await Navigation.PopAsync();
    }
}

iOS

In iOS, lo schema URL personalizzato registrato con Azure Active Directory B2C deve essere registrato in Info.plist. MSAL prevede che lo schema URL rispetti un modello specifico, descritto in precedenza in Registrare l'applicazione per dispositivi mobili con Azure Active Directory B2C. Lo screenshot seguente mostra lo schema URL personalizzato in Info.plist.

MSAL richiede anche diritti Keychain in iOS, registrati in Entitilements.plist, come illustrato nello screenshot seguente:

Quando Azure Active Directory B2C completa la richiesta di autorizzazione, reindirizza all'URL di reindirizzamento registrato. Lo schema URL personalizzato comporta l'avvio dell'applicazione per dispositivi mobili iOS e il passaggio dell'URL come parametro di avvio, in cui viene elaborato dall'override OpenUrl della classe dell'applicazione AppDelegate e restituisce il controllo dell'esperienza a MSAL. L'implementazione OpenUrl è illustrata nell'esempio di codice seguente:

using Microsoft.Identity.Client;

namespace TodoAzure.iOS
{
    [Register("AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
    {
        ...
        public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
        {
            AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(url);
            return base.OpenUrl(app, url, options);
        }
    }
}

Android

In Android, lo schema URL personalizzato registrato con Azure Active Directory B2C deve essere registrato nel AndroidManifest.xml. MSAL prevede che lo schema URL rispetti un modello specifico, descritto in precedenza in Registrare l'applicazione per dispositivi mobili con Azure Active Directory B2C. Nell'esempio seguente viene illustrato lo schema URL personalizzato nella AndroidManifest.xml.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.xamarin.adb2cauthorization">
  <uses-sdk android:minSdkVersion="15" />
  <application android:label="ADB2CAuthorization">
    <activity android:name="microsoft.identity.client.BrowserTabActivity">
      <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <!-- example -->
        <!-- <data android:scheme="msalaaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" android:host="auth" /> -->
        <data android:scheme="INSERT_URI_SCHEME_HERE" android:host="auth" />
      </intent-filter>
    </activity>"
  </application>
</manifest>

La MainActivity classe deve essere modificata per fornire l'oggetto UIParent all'applicazione durante la OnCreate chiamata. Quando Azure Active Directory B2C completa la richiesta di autorizzazione, reindirizza allo schema URL registrato dal AndroidManifest.xml. Lo schema URI registrato restituisce Android che chiama il OnActivityResult metodo con l'URL come parametro di avvio, in cui viene elaborato dal SetAuthenticationContinuationEventArgs metodo .

public class MainActivity : FormsAppCompatActivity
{
    protected override void OnCreate(Bundle bundle)
    {
        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;

        base.OnCreate(bundle);

        Forms.Init(this, bundle);
        LoadApplication(new App());
        App.UIParent = this;
    }

    protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
    {
        base.OnActivityResult(requestCode, resultCode, data);
        AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(requestCode, resultCode, data);
    }
}

Piattaforma UWP (Universal Windows Platform)

Non è necessaria alcuna configurazione aggiuntiva per l'uso di MSAL nel piattaforma UWP (Universal Windows Platform)

Eseguire il progetto

Eseguire l'applicazione in un dispositivo virtuale o fisico. Toccando il pulsante Accedi , aprire il browser e passare a una pagina in cui è possibile accedere o creare un account. Dopo aver completato il processo di accesso, si dovrebbe tornare alla pagina di disconnessione dell'applicazione. Lo screenshot seguente mostra la schermata di accesso dell'utente in esecuzione in Android e iOS: