Guida introduttiva: Accesso per gli utenti e chiamata dell'API Microsoft Graph da un'app di Android

Benvenuto! Questa probabilmente non è la pagina che ti aspettavi. Attualmente stiamo lavorando a una correzione, ma per il momento, usare il collegamento seguente: è consigliabile passare all'articolo corretto:

Guida introduttiva: Accedere agli utenti e chiamare Microsoft Graph da un'app Android

Ci scusiamo per l'inconveniente e apprezziamo la vostra pazienza mentre lavoriamo per risolvere questo problema.

In questa guida di avvio rapido si scarica e si esegue un esempio di codice di un'applicazione Android che consente agli utenti di accedere e ottenere un token di accesso per chiamare l'API Microsoft Graph.

Per un'illustrazione, vedere Funzionamento dell'esempio.

Le applicazioni devono essere rappresentate da un oggetto app in Microsoft Entra ID in modo che Microsoft Identity Platform possa fornire token all'applicazione.

Prerequisiti

Passaggio 1: Configurare l'applicazione nel portale di Azure

Per il funzionamento dell'esempio di codice in questa guida introduttiva, aggiungere un URI di reindirizzamento compatibile con il broker di autenticazione.

Already configured L'applicazione è configurata con questi attributi

Passaggio 2: Scaricare il progetto

Eseguire il progetto con Android Studio.

Passaggio 3: L'app è configurata e pronta per l'esecuzione

Il progetto è stato configurato con i valori delle proprietà dell'app ed è pronto per essere eseguito. L'app di esempio viene avviata nella schermata Single Account Mode (Modalità per account singolo). Per impostazione predefinita, viene fornito un ambito predefinito, user.read, che viene usato durante la lettura dei dati del profilo durante la chiamata all'API Microsoft Graph. L'URL per la chiamata all'API Microsoft Graph viene fornito per impostazione predefinita. Se si desidera, è possibile modificarli entrambi.

MSAL sample app showing single and multiple account usage

Usare il menu dell'app per passare dalla modalità per account singolo a quella per account multipli e viceversa.

Nella modalità per account singolo accedere con un account aziendale o personale:

  1. Selezionare Get graph data interactively (Ottieni i dati del grafo in modo interattivo) per richiedere all'utente le credenziali. L'output della chiamata all'API Microsoft Graph verrà visualizzato nella parte inferiore della schermata.
  2. Dopo l'accesso selezionare Get graph data silently (Ottieni i dati del grafo in modo automatico) per effettuare una chiamata all'API Microsoft Graph senza richiedere di nuovo le credenziali utente. L'output della chiamata all'API Microsoft Graph verrà visualizzato nella parte inferiore della schermata.

Nella modalità per account multipli è possibile ripetere gli stessi passaggi. È anche possibile rimuovere l'account di accesso e di conseguenza rimuovere i token memorizzati nella cache per tale account.

Nota

Enter_the_Supported_Account_Info_Here

Funzionamento dell'esempio

Screenshot of the sample app

Il codice è organizzato in frammenti in cui viene illustrato come scrivere un'app MSAL per account singolo e account multipli. I file di codice sono organizzati come indicato di seguito:

file Dimostra
MainActivity Gestisce l'interfaccia utente
MSGraphRequestWrapper Chiama l'API Microsoft Graph usando il token fornito da MSAL
MultipleAccountModeFragment Inizializza un'applicazione per account multipli, carica un account utente e ottiene un token per chiamare l'API Microsoft Graph
SingleAccountModeFragment Inizializza un'applicazione per account singolo, carica un account utente e ottiene un token per chiamare l'API Microsoft Graph
res/auth_config_multiple_account.json File di configurazione per account multipli
res/auth_config_single_account.json File di configurazione per l'account singolo
Gradle Scripts/build.grade (Module:app) Posizione in cui aggiungere le dipendenze della libreria MSAL

I file verranno ora esaminati in modo più dettagliato e verrà richiamato il codice specifico di MSAL in ognuno di essi.

Aggiungere MSAL all'app

MSAL (com.microsoft.identity.client) è la libreria usata per concedere l'accesso agli utenti e richiedere i token usati per accedere a un'API protetta da Microsoft Identity Platform. Gradle 3.0+ installa la libreria quando si aggiunge quanto segue in Gradle Scripts>build.gradle (Module: app) in Dependencies:

dependencies {
    ...
    implementation 'com.microsoft.identity.client:msal:2.+'
    ...
}

Indica a Gradle di scaricare e compilare MSAL da Maven Central.

È anche necessario aggiungere riferimenti a maven alla parte allprojects>repository della build.gradle (Module: app) come indicato di seguito:

allprojects {
    repositories {
        mavenCentral()
        google()
        mavenLocal()
        maven {
            url 'https://pkgs.dev.azure.com/MicrosoftDeviceSDK/DuoSDK-Public/_packaging/Duo-SDK-Feed/maven/v1'
        }
        maven {
            name "vsts-maven-adal-android"
            url "https://identitydivision.pkgs.visualstudio.com/_packaging/AndroidADAL/maven/v1"
            credentials {
                username System.getenv("ENV_VSTS_MVN_ANDROIDADAL_USERNAME") != null ? System.getenv("ENV_VSTS_MVN_ANDROIDADAL_USERNAME") : project.findProperty("vstsUsername")
                password System.getenv("ENV_VSTS_MVN_ANDROIDADAL_ACCESSTOKEN") != null ? System.getenv("ENV_VSTS_MVN_ANDROIDADAL_ACCESSTOKEN") : project.findProperty("vstsMavenAccessToken")
            }
        }
        jcenter()
    }
}

Importazioni MSAL

Le importazioni pertinenti per la libreria MSAL sono com.microsoft.identity.client.*. Viene ad esempio visualizzato import > com.microsoft.identity.client.PublicClientApplication;, ovvero lo spazio dei nomi per la classe PublicClientApplication, che rappresenta l'applicazione client pubblica.

SingleAccountModeFragment.java

Questo file illustra come creare un'app MSAL per account singolo e chiamare un'API Microsoft Graph.

Le app per account singolo vengono usate solo da un unico utente. Ad esempio, è possibile avere un solo account con cui si accede all'app di mapping.

Inizializzazione di MSAL per account singolo

In auth_config_single_account.json, in onCreateView(), viene creato un account singolo PublicClientApplication usando le informazioni di configurazione archiviate nel file auth_config_single_account.json. Ecco come inizializzare la libreria MSAL per l'uso in un'app MSAL per account singolo:

...
// Creates a PublicClientApplication object with res/raw/auth_config_single_account.json
PublicClientApplication.createSingleAccountPublicClientApplication(getContext(),
        R.raw.auth_config_single_account,
        new IPublicClientApplication.ISingleAccountApplicationCreatedListener() {
            @Override
            public void onCreated(ISingleAccountPublicClientApplication application) {
                /**
                 * This test app assumes that the app is only going to support one account.
                 * This requires "account_mode" : "SINGLE" in the config json file.
                 **/
                mSingleAccountApp = application;
                loadAccount();
            }

            @Override
            public void onError(MsalException exception) {
                displayError(exception);
            }
        });

Accesso di un utente

In SingleAccountModeFragment.java, il codice per l'accesso di un utente è in initializeUI(), nel gestore di clic signInButton.

Chiamare signIn() prima di provare ad acquisire i token. signIn() si comporta come se venisse chiamato acquireToken() e consente di ottenere un prompt interattivo per l'accesso dell'utente.

L'accesso di un utente è un'operazione asincrona. Viene passato un callback che chiama l'API Microsoft Graph e aggiorna l'interfaccia utente dopo che l'utente ha eseguito l'accesso:

mSingleAccountApp.signIn(getActivity(), null, getScopes(), getAuthInteractiveCallback());

Disconnessione di un utente

In SingleAccountModeFragment.java, il codice per la disconnessione di un utente è in initializeUI(), nel gestore di clic signOutButton. La disconnessione di un utente è un'operazione asincrona. La disconnessione dell'utente implica anche la cancellazione della cache dei token per l'account. Viene creato un callback per aggiornare l'interfaccia utente dopo che l'account utente è stato disconnesso:

mSingleAccountApp.signOut(new ISingleAccountPublicClientApplication.SignOutCallback() {
    @Override
    public void onSignOut() {
        updateUI(null);
        performOperationOnSignOut();
    }

    @Override
    public void onError(@NonNull MsalException exception) {
        displayError(exception);
    }
});

Ottenere un token in modo interattivo o automatico

Per fare in modo che all'utente venga presentato il minor numero di richieste, il token viene in genere ottenuto automaticamente. Se si verifica un errore, provare a ottenere il token in modo interattivo. La prima volta che l'app chiama signIn(), funge in realtà da chiamata a acquireToken(), che richiederà all'utente l'immissione delle credenziali.

Ecco alcune situazioni in cui all'utente finale potrebbe essere richiesto di selezionare il proprio account, immettere le credenziali o fornire il consenso per le autorizzazioni richieste dall'app:

  • La prima volta che l'utente accede all'applicazione
  • Se un utente reimposta la password, dovrà immettere le credenziali
  • Se il consenso viene revocato
  • Se l'app richiede esplicitamente il consenso
  • Quando l'applicazione richiede l'accesso a una risorsa per la prima volta
  • Quando è necessario eseguire l'autenticazione a più fattori o soddisfare altri criteri di accesso condizionale

Il codice per ottenere un token in modo interattivo, ovvero visualizzando un'interfaccia utente per richiedere l'input dell'utente, si trova in SingleAccountModeFragment.java, in initializeUI(), nel gestore di clic callGraphApiInteractiveButton:

/**
 * If acquireTokenSilent() returns an error that requires an interaction (MsalUiRequiredException),
 * invoke acquireToken() to have the user resolve the interrupt interactively.
 *
 * Some example scenarios are
 *  - password change
 *  - the resource you're acquiring a token for has a stricter set of requirement than your Single Sign-On refresh token.
 *  - you're introducing a new scope which the user has never consented for.
 **/
mSingleAccountApp.acquireToken(getActivity(), getScopes(), getAuthInteractiveCallback());

Se l'utente ha già eseguito l'accesso, acquireTokenSilentAsync() consente alle app di richiedere i token in modo automatico, come illustrato in >initializeUI(), nel gestore di clic callGraphApiSilentButton:

/**
 * Once you've signed the user in,
 * you can perform acquireTokenSilent to obtain resources without interrupting the user.
 **/
  mSingleAccountApp.acquireTokenSilentAsync(getScopes(), AUTHORITY, getAuthSilentCallback());

Caricare un account

Il codice per caricare un account si trova in SingleAccountModeFragment.java, in loadAccount(). Il caricamento dell'account dell'utente è un'operazione asincrona, di conseguenza i callback da gestire quando l'account viene caricato, cambia o si verifica un errore vengono passati a MSAL. Il codice seguente gestisce anche onAccountChanged(), che si verifica quando un account viene rimosso, l'utente passa a un altro account e così via.

private void loadAccount() {
    ...

    mSingleAccountApp.getCurrentAccountAsync(new ISingleAccountPublicClientApplication.CurrentAccountCallback() {
        @Override
        public void onAccountLoaded(@Nullable IAccount activeAccount) {
            // You can use the account data to update your UI or your app database.
            updateUI(activeAccount);
        }

        @Override
        public void onAccountChanged(@Nullable IAccount priorAccount, @Nullable IAccount currentAccount) {
            if (currentAccount == null) {
                // Perform a cleanup task as the signed-in account changed.
                performOperationOnSignOut();
            }
        }

        @Override
        public void onError(@NonNull MsalException exception) {
            displayError(exception);
        }
    });

Chiamare Microsoft Graph

Quando un utente ha eseguito l'accesso, la chiamata a Microsoft Graph viene effettuata tramite una richiesta HTTP da callGraphAPI(), definito in SingleAccountModeFragment.java. Questa funzione è un wrapper che semplifica l'esempio eseguendo alcune attività, ad esempio il recupero del token di accesso da authenticationResult e la creazione di un pacchetto della chiamata a MSGraphRequestWrapper, nonché visualizzando i risultati della chiamata.

private void callGraphAPI(final IAuthenticationResult authenticationResult) {
    MSGraphRequestWrapper.callGraphAPIUsingVolley(
            getContext(),
            graphResourceTextView.getText().toString(),
            authenticationResult.getAccessToken(),
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    /* Successfully called graph, process data and send to UI */
                    ...
                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    ...
                }
            });
}

auth_config_single_account.json

Questo è il file di configurazione per un'app MSAL che usa un account singolo.

Per una spiegazione di questi campi, vedere Informazioni sul file di configurazione di Android Microsoft Authentication Library (MSAL).

Si noti la presenza di "account_mode" : "SINGLE", che configura l'app per l'uso di un account singolo.

"client_id" è preconfigurato per l'uso di una registrazione dell'oggetto app gestita da Microsoft. "redirect_uri" è preconfigurato per l'uso della chiave di firma fornita con l'esempio di codice.

{
  "client_id" : "0984a7b6-bc13-4141-8b0d-8f767e136bb7",
  "authorization_user_agent" : "DEFAULT",
  "redirect_uri" : "msauth://com.azuresamples.msalandroidapp/1wIqXSqBj7w%2Bh11ZifsnqwgyKrY%3D",
  "account_mode" : "SINGLE",
  "broker_redirect_uri_registered": true,
  "authorities" : [
    {
      "type": "AAD",
      "audience": {
        "type": "AzureADandPersonalMicrosoftAccount",
        "tenant_id": "common"
      }
    }
  ]
}

MultipleAccountModeFragment.java

Questo file illustra come creare un'app MSAL per account multipli e chiamare un'API Microsoft Graph.

Un esempio di app per account multipli è costituito da un'app di posta elettronica che consente di usare più account utente, ad esempio un account aziendale e un account personale.

Inizializzazione di MSAL per account multipli

Nel file MultipleAccountModeFragment.java, in onCreateView(), viene creato un oggetto app per account multiplo (IMultipleAccountPublicClientApplication) usando le informazioni di configurazione archiviate nel file auth_config_multiple_account.json file:

// Creates a PublicClientApplication object with res/raw/auth_config_multiple_account.json
PublicClientApplication.createMultipleAccountPublicClientApplication(getContext(),
        R.raw.auth_config_multiple_account,
        new IPublicClientApplication.IMultipleAccountApplicationCreatedListener() {
            @Override
            public void onCreated(IMultipleAccountPublicClientApplication application) {
                mMultipleAccountApp = application;
                loadAccounts();
            }

            @Override
            public void onError(MsalException exception) {
                ...
            }
        });

L'oggetto MultipleAccountPublicClientApplication creato viene archiviato in una variabile di membro di classe in modo che possa essere usato per interagire con la libreria MSAL allo scopo di acquisire i token e caricare e rimuovere l'account utente.

Caricare un account

Le app per account multipli chiamano in genere getAccounts() per selezionare l'account da usare per le operazioni MSAL. Il codice per caricare un account si trova nel file MultipleAccountModeFragment.java, in loadAccounts(). Il caricamento dell'account dell'utente è un'operazione asincrona. Un callback gestisce quindi le situazioni in cui l'account viene caricato, cambia o si verifica un errore.

/**
 * Load currently signed-in accounts, if there's any.
 **/
private void loadAccounts() {
    if (mMultipleAccountApp == null) {
        return;
    }

    mMultipleAccountApp.getAccounts(new IPublicClientApplication.LoadAccountsCallback() {
        @Override
        public void onTaskCompleted(final List<IAccount> result) {
            // You can use the account data to update your UI or your app database.
            accountList = result;
            updateUI(accountList);
        }

        @Override
        public void onError(MsalException exception) {
            displayError(exception);
        }
    });
}

Ottenere un token in modo interattivo o automatico

Ecco alcune situazioni in cui all'utente finale potrebbe essere richiesto di selezionare il proprio account, immettere le credenziali o fornire il consenso per le autorizzazioni richieste dall'app:

  • La prima volta che gli utenti accedono all'applicazione
  • Se un utente reimposta la password, dovrà immettere le credenziali
  • Se il consenso viene revocato
  • Se l'app richiede esplicitamente il consenso
  • Quando l'applicazione richiede l'accesso a una risorsa per la prima volta
  • Quando è necessario eseguire l'autenticazione a più fattori o soddisfare altri criteri di accesso condizionale

Le app per account multipli devono in genere acquisire token in modo interattivo, ovvero visualizzando un'interfaccia utente per richiedere l'input dell'utente, con una chiamata a acquireToken(). Il codice per ottenere un token in modo interattivo si trova nel file MultipleAccountModeFragment.java in initializeUI> (), nel gestore di clic callGraphApiInteractiveButton:

/**
 * Acquire token interactively. It will also create an account object for the silent call as a result (to be obtained by > getAccount()).
 *
 * If acquireTokenSilent() returns an error that requires an interaction,
 * invoke acquireToken() to have the user resolve the interrupt interactively.
 *
 * Some example scenarios are
 *  - password change
 *  - the resource you're acquiring a token for has a stricter set of requirement than your SSO refresh token.
 *  - you're introducing a new scope which the user has never consented for.
 **/
mMultipleAccountApp.acquireToken(getActivity(), getScopes(), getAuthInteractiveCallback());

Le app non dovrebbero richiedere agli utenti di eseguire l'accesso ogni volta che richiedono un token. Se l'utente ha già eseguito l'accesso, acquireTokenSilentAsync() consente alle app di richiedere i token senza input dell'utente, come illustrato nel file MultipleAccountModeFragment.java, in initializeUI(), nel gestore di clic callGraphApiSilentButton:

/**
 * Performs acquireToken without interrupting the user.
 *
 * This requires an account object of the account you're obtaining a token for.
 * (can be obtained via getAccount()).
 */
mMultipleAccountApp.acquireTokenSilentAsync(getScopes(),
    accountList.get(accountListSpinner.getSelectedItemPosition()),
    AUTHORITY,
    getAuthSilentCallback());

Rimuovere un account

Il codice per rimuovere un account e tutti i token memorizzati nella cache per l'account si trova nel file MultipleAccountModeFragment.java, in initializeUI(), nel gestore del pulsante Rimuovi account. Prima di poter rimuovere un account, è necessario un oggetto account, ottenuto da metodi MSAL come getAccounts() e acquireToken(). Dal momento che la rimozione di un account è un'operazione asincrona, viene fornito il callback onRemoved per aggiornare l'interfaccia utente.

/**
 * Removes the selected account and cached tokens from this app (or device, if the device is in shared mode).
 **/
mMultipleAccountApp.removeAccount(accountList.get(accountListSpinner.getSelectedItemPosition()),
        new IMultipleAccountPublicClientApplication.RemoveAccountCallback() {
            @Override
            public void onRemoved() {
                ...
                /* Reload account asynchronously to get the up-to-date list. */
                loadAccounts();
            }

            @Override
            public void onError(@NonNull MsalException exception) {
                displayError(exception);
            }
        });

auth_config_multiple_account.json

Questo è il file di configurazione per un'app MSAL che usa account multipli.

Per una spiegazione dei vari campi, vedere Informazioni sul file di configurazione di Android Microsoft Authentication Library (MSAL).

A differenza del file di configurazione auth_config_single_account.json, questo file contiene "account_mode" : "MULTIPLE" invece di "account_mode" : "SINGLE" perché si tratta di un'app per account multipli.

"client_id" è preconfigurato per l'uso di una registrazione dell'oggetto app gestita da Microsoft. "redirect_uri" è preconfigurato per l'uso della chiave di firma fornita con l'esempio di codice.

{
  "client_id" : "0984a7b6-bc13-4141-8b0d-8f767e136bb7",
  "authorization_user_agent" : "DEFAULT",
  "redirect_uri" : "msauth://com.azuresamples.msalandroidapp/1wIqXSqBj7w%2Bh11ZifsnqwgyKrY%3D",
  "account_mode" : "MULTIPLE",
  "broker_redirect_uri_registered": true,
  "authorities" : [
    {
      "type": "AAD",
      "audience": {
        "type": "AzureADandPersonalMicrosoftAccount",
        "tenant_id": "common"
      }
    }
  ]
}

Assistenza e supporto

Se è necessaria assistenza, si vuole segnalare un problema o si vogliono ottenere informazioni sulle opzioni di supporto, vedere Assistenza e supporto per gli sviluppatori.

Passaggi successivi

Procedere con l'esercitazione su Android in cui viene creata un'app Android che ottiene un token di accesso da Microsoft Identity Platform e lo usa per chiamare l'API Microsoft Graph.