Autenticare gli utenti con Azure Active Directory B2C

Scaricare l'esempio Scaricare l'esempio

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 ai consumer. Consente agli utenti di accedere all'applicazione usando gli account di social network esistenti o credenziali personalizzate, ad esempio posta elettronica, nome utente e password. Gli account credenziali personalizzati vengono definiti account locali.

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

  1. Creare un tenant Azure Active Directory B2C.
  2. Registrare l'applicazione per dispositivi mobili Azure Active Directory tenant B2C.
  3. Creare criteri per l'iscrizione e l'accesso e dimenticare i flussi utente delle password.
  4. Usare Microsoft Authentication Library (MSAL) per avviare un flusso di lavoro di autenticazione con il tenant 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à Azure Active Directory B2C, vedere Azure Active Directory documentazione di B2C.

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

Configurare un tenant Azure Active Directory B2C

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

Dopo aver creato un tenant, saranno necessari 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/https://contoso20190410tenant.onmicrosoft.com/ è contoso20190410tenant.onmicrosoft.com e il nome del contoso20190410tenant.onmicrosoft.com è contoso20190410tenant . Trovare il dominio tenant nella portale di Azure facendo clic sul filtro directory e sottoscrizione nel menu in alto. Lo screenshot seguente mostra il pulsante Filtro directory e sottoscrizione di Azure e il dominio tenant:

Nome del tenant nella vista filtro directory e sottoscrizione di Azure

Nel progetto di esempio modificare il file Constants.cs per impostare i campi e tenantId . Il codice seguente illustra come impostare questi valori se il dominio del tenant è , sostituire questi valori https://contoso20190410tenant.onmicrosoft.com/ 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 Azure Active Directory B2C

Un'applicazione per dispositivi mobili deve essere registrata con il tenant prima di poter connettere e autenticare gli utenti. Il processo di registrazione assegna un ID applicazione univoco all'applicazione e un URL di reindirizzamento che reindirizza le risposte all'applicazione dopo l'autenticazione. Per altre informazioni, vedere Azure Active Directory B2C: Registrare l'applicazione. È 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 di Azure

Microsoft Authentication Library prevede che l'URL di reindirizzamento per l'applicazione sia l'ID applicazione 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 native client 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 nelApplicationManifest.xmlAndroid che in Info.plistdi iOS.

Nel progetto di esempio modificare il file Constants.cs per impostare il campo sull'ID applicazione. Il codice seguente illustra 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 dimenticare i criteri password

Un criterio è un'esperienza che gli utenti possono eseguire 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 torna dall'esperienza. È necessario configurare criteri per l'iscrizione e l'accesso all'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 l'installazione dei criteri, nella vista Flussi utente (criteri) nella finestra di dialogo portale di Azure. Lo screenshot seguente illustra due criteri configurati nel 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 campi e in modo che riflettano i nomi scelti durante policyPassword 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 .NET Standard condiviso e ai progetti della piattaforma in una Xamarin.Forms soluzione. MSAL include una PublicClientApplicationBuilder classe che costruisce un oggetto che rispetta l'interfaccia. IPublicClientApplication MSAL usa With clausole 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 e e crea un'istanza dell'oggetto nel UIParentAuthenticationClient costruttore. La WithIosKeychainSecurityGroup clausola fornisce un nome di gruppo di sicurezza per le applicazioni iOS. La WithB2CAuthority clausola fornisce il criterio WithB2CAuthority, o , che verrà usato 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 nell'istanza di Hub di notifica di Azure è definito un solo URI di reindirizzamento, l'istanza può funzionare senza specificare AuthenticationClient l'URI di reindirizzamento con la WithRedirectUri clausola . Tuttavia, è necessario specificare sempre questo valore nel caso in cui la configurazione di Azure si espandono per supportare altri client o metodi di autenticazione.

Gestore OnAppearing eventi nelle chiamate code-behind OnAppearing per aggiornare il token di autenticazione per gli utenti che hanno AcquireTokenSilentAsync eseguito l'accesso in precedenza. Il processo di autenticazione reindirizza a se LogoutPage ha esito positivo e non esegue alcuna operazione in caso di errore. L'esempio seguente illustra 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 gestore eventi (generato quando si fa clic sul OnLoginButtonClicked pulsante Login) chiama AcquireTokenAsync . La libreria MSAL apre automaticamente il browser dei dispositivi mobili e passa alla pagina di accesso. L'URL di accesso, denominato autorità, è una combinazione del nome del tenant e dei criteri 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 criteri personalizzati. OnForgotPasswordusa un overload diverso di AcquireTokenAsync , che consente di fornire un'autorità OnForgotPassword L'esempio seguente illustra come fornire un'autorità personalizzata quando si acquisisce 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;
        }
    }
}

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

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 i 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 da parte di iOS e il passaggio dell'URL come parametro di avvio, in cui viene elaborato dall'override della classe dell'applicazione, e restituisce il controllo OpenUrl dell'esperienza a AppDelegate MSAL. OpenUrlL'implementazione è 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 nelAndroidManifest.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 nell'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 UIParent l'oggetto all'applicazione durante la OnCreate chiamata. Quando Azure Active Directory B2C completa la richiesta di autorizzazione, reindirizza lo schema URL registrato dalAndroidManifest.xml. Lo schema URI registrato comporta la chiamata del metodo da parte di Android con l'URL come parametro di avvio, in cui viene OnActivityResult 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 usare MSAL nella piattaforma Windows Universal

Eseguire il progetto

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