Aggiungere l'autenticazione all'app Windows

In questo argomento viene illustrato come aggiungere l'autenticazione basata su cloud all’app per dispositivi mobili. In questa esercitazione si aggiungerà l'autenticazione al progetto di guida introduttiva UWP (Universal Windows Platform) per App per dispositivi mobili tramite un provider di identità supportato dal Servizio app di Azure. In seguito all'autenticazione e all'autorizzazione da parte dell'app per dispositivi mobili, viene visualizzato il valore dell'ID utente.

Questa esercitazione è basata sulla guida introduttiva di App per dispositivi mobili. È necessario completare prima l'esercitazione relativa alla creazione di un'app per dispositivi mobili.

Registrare l'app per l'autenticazione e configurare il servizio app

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 url_scheme_of_your_app://easyauth.callback. Il valore url_scheme_of_your_app 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.

A questo punto, è possibile verificare che l'accesso anonimo al back-end è stato disabilitato. Dopo aver impostato il progetto di app UWP come progetto di avvio, distribuire ed eseguire l'app. Verificare che dopo l'avvio dell'app venga generata un'eccezione non gestita con codice di stato 401 (Non autorizzato). L'eccezione non gestita viene generata perché l'app prova ad accedere al codice dell'app per dispositivi mobili come utente non autenticato, mentre la tabella TodoItem richiede ora l'autenticazione.

A questo punto, si aggiornerà l'app in modo che autentichi gli utenti prima di richiedere risorse al servizio mobile.

Aggiungere l'autenticazione all'app

  1. Nel file del progetto dell'app UWP MainPage.xaml.cs aggiungere il frammento di codice seguente:

     // Define a member variable for storing the signed-in user. 
     private MobileServiceUser user;
    
     // Define a method that performs the authentication process
     // using a Facebook sign-in. 
     private async System.Threading.Tasks.Task<bool> AuthenticateAsync()
     {
         string message;
         bool success = false;
         try
         {
             // Change 'MobileService' to the name of your MobileServiceClient instance.
             // Sign-in using Facebook authentication.
             user = await App.MobileService
                 .LoginAsync(MobileServiceAuthenticationProvider.Facebook, "{url_scheme_of_your_app}");
             message =
                 string.Format("You are now signed in - {0}", user.UserId);
    
             success = true;
         }
         catch (InvalidOperationException)
         {
             message = "You must log in. Login Required";
         }
    
         var dialog = new MessageDialog(message);
         dialog.Commands.Add(new UICommand("OK"));
         await dialog.ShowAsync();
         return success;
     }
    

    L'utente viene autenticato nel codice tramite un account di accesso di Facebook. Se si usa un provider di identità diverso da Facebook, sostituire il valore di MobileServiceAuthenticationProvider con il nome del provider.

  2. Sostituire il metodo OnNavigatedTo() in MainPage.xaml.cs. A questo punto aggiungere un pulsante di accesso all'app che attiva l'autenticazione.

     protected override async void OnNavigatedTo(NavigationEventArgs e)
     {
         if (e.Parameter is Uri)
         {
             App.MobileService.ResumeWithURL(e.Parameter as Uri);
         }
     }
    
  3. Aggiungere il seguente frammento di codice a MainPage.xaml.cs:

     private async void ButtonLogin_Click(object sender, RoutedEventArgs e)
     {
         // Login the user and then load data from the mobile app.
         if (await AuthenticateAsync())
         {
             // Switch the buttons and load items from the mobile app.
             ButtonLogin.Visibility = Visibility.Collapsed;
             ButtonSave.Visibility = Visibility.Visible;
             //await InitLocalStoreAsync(); //offline sync support.
             await RefreshTodoItems();
         }
     }
    
  4. Aprire il file di progetto MainPage.xaml, individuare l'elemento che definisce il pulsante Save e sostituirlo con il codice seguente:

     <Button Name="ButtonSave" Visibility="Collapsed" Margin="0,8,8,0" 
             Click="ButtonSave_Click">
         <StackPanel Orientation="Horizontal">
             <SymbolIcon Symbol="Add"/>
             <TextBlock Margin="5">Save</TextBlock>
         </StackPanel>
     </Button>
     <Button Name="ButtonLogin" Visibility="Visible" Margin="0,8,8,0" 
             Click="ButtonLogin_Click" TabIndex="0">
         <StackPanel Orientation="Horizontal">
             <SymbolIcon Symbol="Permissions"/>
             <TextBlock Margin="5">Sign in</TextBlock> 
         </StackPanel>
     </Button>
    
  5. Aggiungere il seguente frammento di codice ad App.xaml.cs:

     protected override void OnActivated(IActivatedEventArgs args)
     {
         if (args.Kind == ActivationKind.Protocol)
         {
             ProtocolActivatedEventArgs protocolArgs = args as ProtocolActivatedEventArgs;
             Frame content = Window.Current.Content as Frame;
             if (content.Content.GetType() == typeof(MainPage))
             {
                 content.Navigate(typeof(MainPage), protocolArgs.Uri);
             }
         }
         Window.Current.Activate();
         base.OnActivated(args);
     }
    
  6. Aprire il file Package.appxmanifest, passare a Dichiarazioni nell'elenco a discesa Dichiarazioni disponibili, selezionare Protocollo e fare clic sul pulsante Aggiungi. Configurare ora le Proprietà della dichiarazione Protocollo. In Nome visualizzato aggiungere il nome da mostrare agli utenti dell'applicazione. In Nome aggiungere il valore {url_scheme_of_your_app}.
  7. Premere il tasto F5 per eseguire l'app, fare clic sul pulsante Sign in e accedere all'app con il provider di identità scelto. Dopo che l'accesso è stato completato, l'app funziona senza errori ed è possibile eseguire query nel back-end e aggiornare i dati.

Archiviare il token di autenticazione sul client

Nell'esempio precedente è stato illustrato un accesso standard, che richiede al client di contattare sia il provider di identità sia il servizio app ogni volta che l'app viene avviata. Non solo questo metodo è inefficiente, ma si potrebbero riscontrare problemi relativi all'uso qualora molti clienti provassero ad avviare l'app contemporaneamente. Un miglior approccio consiste nel memorizzare nella cache il token di autorizzazione restituito dal servizio app e provare a usare questo prima di usare un accesso basato su provider.

Nota

È possibile memorizzare nella cache il token rilasciato dai Servizi app indipendentemente dal fatto che si usi l'autenticazione gestita dal client o gestita dal servizio. In questa esercitazione viene usata l'autenticazione gestita dal servizio.

  1. Nel file di progetto MainPage.xaml.cs aggiungere le istruzioni using seguenti:

     using System.Linq;        
     using Windows.Security.Credentials;
    
  2. Sostituire il metodo AuthenticateAsync con il codice seguente:

     private async System.Threading.Tasks.Task<bool> AuthenticateAsync()
     {
         string message;
         bool success = false;
    
         // This sample uses the Facebook provider.
         var provider = MobileServiceAuthenticationProvider.Facebook;
    
         // Use the PasswordVault to securely store and access credentials.
         PasswordVault vault = new PasswordVault();
         PasswordCredential credential = null;
    
         try
         {
             // Try to get an existing credential from the vault.
             credential = vault.FindAllByResource(provider.ToString()).FirstOrDefault();
         }
         catch (Exception)
         {
             // When there is no matching resource an error occurs, which we ignore.
         }
    
         if (credential != null)
         {
             // Create a user from the stored credentials.
             user = new MobileServiceUser(credential.UserName);
             credential.RetrievePassword();
             user.MobileServiceAuthenticationToken = credential.Password;
    
             // Set the user from the stored credentials.
             App.MobileService.CurrentUser = user;
    
             // Consider adding a check to determine if the token is 
             // expired, as shown in this post: http://aka.ms/jww5vp.
    
             success = true;
             message = string.Format("Cached credentials for user - {0}", user.UserId);
         }
         else
         {
             try
             {
                 // Login with the identity provider.
                 user = await App.MobileService
                     .LoginAsync(provider);
    
                 // Create and store the user credentials.
                 credential = new PasswordCredential(provider.ToString(),
                     user.UserId, user.MobileServiceAuthenticationToken);
                 vault.Add(credential);
    
                 success = true;
                 message = string.Format("You are now logged in - {0}", user.UserId);
             }
             catch (MobileServiceInvalidOperationException)
             {
                 message = "You must log in. Login Required";
             }
         }
    
         var dialog = new MessageDialog(message);
         dialog.Commands.Add(new UICommand("OK"));
         await dialog.ShowAsync();
    
         return success;
     }
    

    In questa versione di AuthenticateAsync, l'app tenta di usare le credenziali archiviate in PasswordVault per accedere al servizio. Un accesso normale viene eseguito anche quando non sono disponibili credenziali archiviate.

    Nota

    Un token memorizzato nella cache potrebbe essere scaduto, ma la scadenza del token può avvenire anche dopo l'autenticazione mentre l'app è in uso. Per informazioni su come determinare se un token è scaduto, vedere Cercare i token di autenticazione scaduti. Per una soluzione relativa alla gestione degli errori di autorizzazione relativi ai token scaduti, vedere il post sulla memorizzazione nella cache e la gestione dei token scaduti nell'SDK per il codice gestito di Servizi mobili di Azure.

  3. Riavviare l'app due volte.

    Si noti che al primo avvio viene di nuovo richiesto l'accesso con il provider. Al secondo riavvio, invece, verranno usate le credenziali memorizzate nella cache e l'accesso sarà ignorato.

Passaggi successivi

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