Aggiungere l'autenticazione all'app Android

Riepilogo

Questa esercitazione spiega come aggiungere l'autenticazione al progetto introduttivo TodoList in Android tramite un provider di identità supportato. Questa esercitazione è basata sull'esercitazione Introduzione ad App per dispositivi mobili, che deve essere completata per prima.

Registrare l'app per l'autenticazione e configurare Servizio app di Azure

Innanzitutto, è necessario registrare l'app nel sito di un provider di identità e quindi impostare le credenziali generate dal provider nel back-end dell'app per dispositivi mobili.

  1. Configurare il provider di identità preferito seguendo le istruzioni specifiche del provider:

  2. Ripetere i passaggi precedenti per ogni provider di cui si desidera il supporto nell'app.

Aggiungere l'app agli URL di reindirizzamento esterni consentiti

L'autenticazione sicura richiede la definizione di un nuovo schema URL per l'app. In questo modo il sistema di autenticazione reindirizza all'app al termine del processo di autenticazione. In questa esercitazione si usa lo schema URL appname. È tuttavia possibile usare QUALSIASI schema URL. Lo schema deve essere univoco per l'applicazione per dispositivi mobili. Per abilitare il reindirizzamento sul lato server:

  1. Nel [portale di Azure] selezionare il servizio app.

  2. Fare clic sull'opzione di menu Autenticazione/Autorizzazione.

  3. In URL di reindirizzamento esterni consentiti specificare appname://easyauth.callback. Il valore appname in questa stringa è lo schema URL per l'applicazione per dispositivi mobili. Deve seguire le normale specifica URL per un protocollo, ovvero usare solo lettere e numeri e iniziare con una lettera. È opportuno prendere nota della stringa scelta perché sarà necessario modificare il codice dell'applicazione per dispositivi mobili con lo schema URL in diverse posizioni.

  4. Fare clic su OK.

  5. Fare clic su Save.

Limitare le autorizzazioni agli utenti autenticati

Per impostazione predefinita, le API in un back-end dell'app per dispositivi mobili possono essere richiamate in modo anonimo. È necessario limitare l'accesso solo ai client autenticati.

  • Back-end Node. js nuovamente fine (tramite il Portale di Azure) :

    Nelle impostazioni dell'app per dispositivi mobili fare clic su Tabelle semplici e selezionare la tabella. Fare clic su Modifica autorizzazioni, selezionare Authenticated access only (Solo accesso con autenticazione) per tutte le autorizzazioni e quindi fare clic su Salva.

  • Back-end. NET (C#):

    Nel progetto server passare a Controller > TodoItemController.cs. Aggiungere l'attributo [Authorize] alla classe TodoItemController, come indicato di seguito. Per limitare l'accesso solo a metodi specifici, è inoltre possibile applicare questo attributo solo a tali metodi anziché alla classe. Pubblicare di nuovo il progetto server.

      [Authorize]
      public class TodoItemController : TableController<TodoItem>
    
  • Back-end Node.js (tramite codice Node.js) :

    Per richiedere l'autenticazione per l'accesso alla tabella, aggiungere la riga seguente allo script del server Node.js:

      table.access = 'authenticated';
    

    Per altre informazioni, vedere Procedura: Richiedere l'autenticazione per l'accesso alle tabelle. Per informazioni su come scaricare il progetto di codice di avvio rapido dal sito, vedere Procedura: Scaricare il progetto di codice di avvio rapido del back-end Node.js tramite Git.

  • In Android Studio aprire il progetto completato con l'esercitazione Introduzione ad App per dispositivi mobili. Dal menu Run fare clic su Run app e verificare che, dopo l'avvio dell'app, venga generata un'eccezione non gestita con codice di stato 401 (Non autorizzata).

    Questa eccezione viene generata perché l'app tenta di accedere al back-end come utente non autenticato, mentre la tabella TodoItem richiede ora l'autenticazione.

A questo punto, si aggiorna l'app in modo che autentichi gli utenti prima di richiedere risorse al back-end di App per dispositivi mobili.

Aggiungere l'autenticazione all'app

  1. Aprire il progetto in Android Studio.

  2. In Project Explorer (Esplora progetti) in Android Studio aprire il file ToDoActivity.java e aggiungere le istruzioni import seguenti:

     import java.util.concurrent.ExecutionException;
     import java.util.concurrent.atomic.AtomicBoolean;
    
     import android.content.Context;
     import android.content.SharedPreferences;
     import android.content.SharedPreferences.Editor;
    
     import com.microsoft.windowsazure.mobileservices.authentication.MobileServiceAuthenticationProvider;
     import com.microsoft.windowsazure.mobileservices.authentication.MobileServiceUser;
    
  3. Aggiungere il metodo seguente alla classe ToDoActivity :

     // You can choose any unique number here to differentiate auth providers from each other. Note this is the same code at login() and onActivityResult().
     public static final int GOOGLE_LOGIN_REQUEST_CODE = 1;
    
     private void authenticate() {
         // Login using the Google provider.
         mClient.login("Google", "{url_scheme_of_your_app}", GOOGLE_LOGIN_REQUEST_CODE);
     }
    
     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         // When request completes
         if (resultCode == RESULT_OK) {
             // Check the request code matches the one we send in the login request
             if (requestCode == GOOGLE_LOGIN_REQUEST_CODE) {
                 MobileServiceActivityResult result = mClient.onActivityResult(data);
                 if (result.isLoggedIn()) {
                     // login succeeded
                     createAndShowDialog(String.format("You are now logged in - %1$2s", mClient.getCurrentUser().getUserId()), "Success");
                     createTable();
                 } else {
                     // login failed, check the error message
                     String errorMessage = result.getErrorMessage();
                     createAndShowDialog(errorMessage, "Error");
                 }
             }
         }
     }
    

    Questo codice crea un metodo per gestire il processo di autenticazione di Google. Una finestra di dialogo riporta l'ID dell'utente autenticato. È possibile procedere unicamente se l'autenticazione ha esito positivo.

    Nota

    Se si usa un provider di identità diverso da Google, sostituire il valore passato al metodo login con uno dei valori seguenti: MicrosoftAccount, Facebook, Twitter o windowsazureactivedirectory.

  4. Nel metodo onCreate aggiungere la riga di codice seguente dopo il codice che crea un'istanza dell'oggetto MobileServiceClient.

     authenticate();
    

    Questa chiamata avvia il processo di autenticazione.

  5. Spostare il codice rimanente dopo authenticate(); nel metodo onCreate in un nuovo metodo createTable:

     private void createTable() {
    
         // Get the table instance to use.
         mToDoTable = mClient.getTable(ToDoItem.class);
    
         mTextNewToDo = (EditText) findViewById(R.id.textNewToDo);
    
         // Create an adapter to bind the items with the view.
         mAdapter = new ToDoItemAdapter(this, R.layout.row_list_to_do);
         ListView listViewToDo = (ListView) findViewById(R.id.listViewToDo);
         listViewToDo.setAdapter(mAdapter);
    
         // Load the items from Azure.
         refreshItemsFromTable();
     }
    
  6. Per assicurarsi che il reindirizzamento funzioni come previsto, aggiungere il frammento di RedirectUrlActivity seguente ad AndroidManifest.xml:

     <activity android:name="com.microsoft.windowsazure.mobileservices.authentication.RedirectUrlActivity">
         <intent-filter>
             <action android:name="android.intent.action.VIEW" />
             <category android:name="android.intent.category.DEFAULT" />
             <category android:name="android.intent.category.BROWSABLE" />
             <data android:scheme="{url_scheme_of_your_app}"
                 android:host="easyauth.callback"/>
         </intent-filter>
     </activity>
    
  7. Aggiungere redirectUriScheme a build.gradle dell'applicazione Android.

     android {
         buildTypes {
             release {
                 // … …
                 manifestPlaceholders = ['redirectUriScheme': '{url_scheme_of_your_app}://easyauth.callback']
             }
             debug {
                 // … …
                 manifestPlaceholders = ['redirectUriScheme': '{url_scheme_of_your_app}://easyauth.callback']
             }
         }
     }
    
  8. Aggiungere com.android.support:customtabs:23.0.1 alle dipendenze in build.gradle:

    dependencies { // ... compile 'com.android.support:customtabs:23.0.1' }

  9. Scegliere Run app (Esegui app) dal menu Esegui per avviare l'app e accedere con il provider di identità scelto.

Avviso

Lo schema URL indicato rispetta la distinzione tra maiuscole e minuscole. Assicurarsi che tutte le occorrenze di {url_scheme_of_you_app} abbiano le stesse maiuscole e minuscole.

Dopo avere eseguito l'accesso, l'app dovrebbe funzionare senza errori e dovrebbe essere possibile eseguire query sul servizio back-end e aggiornare i dati.

Memorizzare nella cache i token di autenticazione sul client

L'esempio precedente illustra un accesso standard che richiede al client di contattare sia il provider di identità sia il servizio back-end di Azure ogni volta che l'app viene avviata. Questo metodo risulta inefficiente e può creare problemi relativi all'uso se più clienti tentano di avviare l'app contemporaneamente. Un miglior approccio consiste nel memorizzare nella cache il token di autorizzazione restituito dal servizio Azure e provare a usarlo prima di un accesso basato su provider.

Nota

È possibile memorizzare nella cache il token rilasciato dal servizio back-end di Azure indipendentemente dal fatto che si usi l'autenticazione gestita dal client o dal servizio. In questa esercitazione viene usata l'autenticazione gestita dal servizio.

  1. Aprire il file ToDoActivity.java e quindi aggiungere le istruzioni import seguenti:

     import android.content.Context;
     import android.content.SharedPreferences;
     import android.content.SharedPreferences.Editor;
    
  2. Aggiungere i membri seguenti alla classe ToDoActivity :

     public static final String SHAREDPREFFILE = "temp";    
     public static final String USERIDPREF = "uid";    
     public static final String TOKENPREF = "tkn";    
    
  3. Nel file ToDoActivity.java aggiungere la definizione seguente per il metodo cacheUserToken.

     private void cacheUserToken(MobileServiceUser user)
     {
         SharedPreferences prefs = getSharedPreferences(SHAREDPREFFILE, Context.MODE_PRIVATE);
         Editor editor = prefs.edit();
         editor.putString(USERIDPREF, user.getUserId());
         editor.putString(TOKENPREF, user.getAuthenticationToken());
         editor.commit();
     }    
    

    Questo metodo consente di memorizzare l'ID utente e il token in un file delle preferenze contrassegnato come privato. In questo modo è possibile proteggere l'accesso alla cache, affinché le altre app sul dispositivo non possano accedere al token. La preferenza è in modalità sandbox per l'applicazione. Tuttavia, se qualcuno riesce ad accedere al dispositivo, è possibile che riesca accedere anche alla cache dei token con altri mezzi.

    Nota

    È possibile proteggere ulteriormente il token con la crittografia se l'accesso token ai dati è considerato altamente sensibile e qualcuno potrebbe accedere al dispositivo. Tuttavia, una soluzione del tutto sicura esula dall'ambito di questa esercitazione e dipende dai rispettivi requisiti di sicurezza.

  4. Nel file ToDoActivity.java aggiungere la definizione seguente per il metodo loadUserTokenCache.

     private boolean loadUserTokenCache(MobileServiceClient client)
     {
         SharedPreferences prefs = getSharedPreferences(SHAREDPREFFILE, Context.MODE_PRIVATE);
         String userId = prefs.getString(USERIDPREF, null);
         if (userId == null)
             return false;
         String token = prefs.getString(TOKENPREF, null);
         if (token == null)
             return false;
    
         MobileServiceUser user = new MobileServiceUser(userId);
         user.setAuthenticationToken(token);
         client.setCurrentUser(user);
    
         return true;
     }
    
  5. Nel file ToDoActivity.java sostituire il metodo authenticate con il metodo seguente, che usa una cache dei token. Modificare il provider di accesso se si vuole usare un account diverso da Google.

     private void authenticate() {
         // We first try to load a token cache if one exists.
         if (loadUserTokenCache(mClient))
         {
             createTable();
         }
         // If we failed to load a token cache, login and create a token cache
         else
         {
             // Login using the Google provider.    
             ListenableFuture<MobileServiceUser> mLogin = mClient.login(MobileServiceAuthenticationProvider.Google);
    
             Futures.addCallback(mLogin, new FutureCallback<MobileServiceUser>() {
                 @Override
                 public void onFailure(Throwable exc) {
                     createAndShowDialog("You must log in. Login Required", "Error");
                 }           
                 @Override
                 public void onSuccess(MobileServiceUser user) {
                     createAndShowDialog(String.format(
                             "You are now logged in - %1$2s",
                             user.getUserId()), "Success");
                     cacheUserToken(mClient.getCurrentUser());
                     createTable();    
                 }
             });
         }
     }
    
  6. Creare l'app e testare l'autenticazione con un account valido. Eseguirla almeno due volte. Durante la prima esecuzione, si riceverà un prompt di accesso per creare la cache dei token. Successivamente, ogni esecuzione tenta di caricare la cache dei token per l'autenticazione. Non viene richiesto di effettuare l'accesso.

Passaggi successivi

Dopo aver completato questa esercitazione sull'autenticazione di base, provare a continuare fino a una delle esercitazioni seguenti:

  • Aggiungere notifiche push all'app Android. Informazioni su come configurare App per dispositivi mobili in modo da utilizzare l'Hub di notifica di Azure per inviare notifiche push.
  • Attivare la sincronizzazione offline per l'app Android. Informazioni su come aggiungere il supporto offline all'app usando il back-end di App per dispositivi mobili. Con la sincronizzazione offline è possibile interagire con un'app per dispositivi mobili —visualizzando, aggiungendo e modificando i dati— anche quando non è disponibile una connessione di rete.