Autenticare gli utenti con un database di documenti di Azure Cosmos DB e Xamarin.Forms

Download Sample Scaricare l'esempio

I database di documenti di Azure Cosmos DB supportano raccolte partizionate, che possono estendersi su più server e partizioni, supportando al contempo archiviazione e velocità effettiva illimitate. Questo articolo illustra come combinare il controllo di accesso con le raccolte partizionate, in modo che un utente possa accedere solo ai propri documenti in un'applicazione Xamarin.Forms .

Panoramica

È necessario specificare una chiave di partizione quando si crea una raccolta partizionata e i documenti con la stessa chiave di partizione verranno archiviati nella stessa partizione. Pertanto, specificando l'identità dell'utente come chiave di partizione, verrà creata una raccolta partizionata che archivierà solo i documenti per tale utente. Ciò garantisce anche che il database di documenti di Azure Cosmos DB venga ridimensionato man mano che aumenta il numero di utenti ed elementi.

L'accesso deve essere concesso a qualsiasi raccolta e il modello di controllo di accesso di Azure Cosmos DB per NoSQL definisce due tipi di costrutti di accesso:

  • Le chiavi master consentono l'accesso amministrativo completo a tutte le risorse all'interno di un account Azure Cosmos DB e vengono create quando viene creato un account Azure Cosmos DB.
  • I token di risorsa acquisisce la relazione tra l'utente di un database e l'autorizzazione che l'utente ha per una risorsa specifica di Azure Cosmos DB, ad esempio una raccolta o un documento.

L'esposizione di una chiave master apre un account Azure Cosmos DB alla possibilità di uso dannoso o trascurabile. Tuttavia, i token delle risorse di Azure Cosmos DB forniscono un meccanismo sicuro per consentire ai client di leggere, scrivere ed eliminare risorse specifiche in un account Azure Cosmos DB in base alle autorizzazioni concesse.

Un approccio tipico alla richiesta, alla generazione e alla distribuzione di token di risorse a un'applicazione per dispositivi mobili consiste nell'usare un gestore di token di risorse. Il diagramma seguente mostra una panoramica generale del modo in cui l'applicazione di esempio usa un gestore di token di risorse per gestire l'accesso ai dati del database dei documenti:

Document Database Authentication Process

Il gestore di token di risorse è un servizio API Web di livello intermedio, ospitato nel servizio app Azure, che possiede la chiave master dell'account Azure Cosmos DB. L'applicazione di esempio usa il gestore di token di risorse per gestire l'accesso ai dati del database di documenti come indicato di seguito:

  1. All'accesso, l'applicazione Xamarin.Forms contatta app Azure servizio per avviare un flusso di autenticazione.
  2. app Azure Servizio esegue un flusso di autenticazione OAuth con Facebook. Al termine del flusso di autenticazione, l'applicazione Xamarin.Forms riceve un token di accesso.
  3. L'applicazione Xamarin.Forms usa il token di accesso per richiedere un token di risorsa dal gestore di token di risorse.
  4. Il gestore di token di risorse usa il token di accesso per richiedere l'identità dell'utente da Facebook. L'identità dell'utente viene quindi usata per richiedere un token di risorsa da Azure Cosmos DB, usato per concedere l'accesso in lettura/scrittura alla raccolta partizionata dell'utente autenticato.
  5. L'applicazione Xamarin.Forms usa il token di risorsa per accedere direttamente alle risorse di Azure Cosmos DB con le autorizzazioni definite dal token della risorsa.

Nota

Quando il token di risorsa scade, le successive richieste di database di documenti riceveranno un'eccezione 401 non autorizzata. A questo punto, Xamarin.Forms le applicazioni devono ristabilire l'identità e richiedere un nuovo token di risorsa.

Per altre informazioni sul partizionamento di Azure Cosmos DB, vedere Come partizionare e ridimensionare in Azure Cosmos DB. Per altre informazioni sul controllo di accesso di Azure Cosmos DB, vedere Protezione dell'accesso ai dati e al controllo di accesso di Azure Cosmos DB in Azure Cosmos DB per NoSQL.

Attrezzaggio

Il processo di integrazione del broker di token di risorse in un'applicazione Xamarin.Forms è il seguente:

  1. Creare un account Azure Cosmos DB che userà il controllo di accesso. Per altre informazioni, vedere Configurazione di Azure Cosmos DB.
  2. Creare un servizio app Azure per ospitare il gestore di token di risorse. Per altre informazioni, vedere app Azure Configurazione del servizio.
  3. Creare un'app Facebook per eseguire l'autenticazione. Per altre informazioni, vedi Facebook Configurazione app.
  4. Configurare il servizio app Azure per eseguire facilmente l'autenticazione con Facebook. Per altre informazioni, vedere app Azure Configurazione dell'autenticazione del servizio.
  5. Configurare l'applicazione Xamarin.Forms di esempio per comunicare con app Azure Service e Azure Cosmos DB. Per altre informazioni, vedere Xamarin.Forms Configurazione dell'applicazione.

Nota

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

Configurazione di Azure Cosmos DB

Il processo di creazione di un account Azure Cosmos DB che userà il controllo di accesso è il seguente:

  1. Creare un account Azure Cosmos DB. Per altre informazioni, vedere Creare un account Azure Cosmos DB.
  2. Nell'account Azure Cosmos DB creare una nuova raccolta denominata UserItems, specificando una chiave di partizione di /userid.

Configurazione del servizio app Azure

Il processo per l'hosting del gestore di token di risorse in app Azure Servizio è il seguente:

  1. Nella portale di Azure creare una nuova app Web servizio app. Per altre informazioni, vedere Creare un'app Web in un ambiente del servizio app.

  2. Nel portale di Azure aprire il pannello App Impostazioni per l'app Web e aggiungere le impostazioni seguenti:

    • accountUrl : il valore deve essere l'URL dell'account Azure Cosmos DB nel pannello Chiavi dell'account Azure Cosmos DB.
    • accountKey : il valore deve essere la chiave master di Azure Cosmos DB (primaria o secondaria) dal pannello Chiavi dell'account Azure Cosmos DB.
    • databaseId : il valore deve essere il nome del database Azure Cosmos DB.
    • collectionId : il valore deve essere il nome della raccolta di Azure Cosmos DB (in questo caso, UserItems).
    • hostUrl: il valore deve essere l'URL dell'app Web nel pannello Panoramica dell'account servizio app.

    Lo screenshot seguente illustra questa configurazione:

    App Service Web App Settings

  3. Pubblicare la soluzione broker di token di risorse nell'app Web del servizio app Azure.

Facebook Configurazione app

Il processo di creazione di un'app Facebook per eseguire l'autenticazione è il seguente:

  1. Creare un'app Facebook. Per altre informazioni, vedere Registrare e configurare un'app nel Centro per sviluppatori di Facebook.
  2. Aggiungere il prodotto Facebook Login all'app. Per altre informazioni, vedi Aggiungere l'account di accesso di Facebook all'app o al sito Web nel Centro per sviluppatori di Facebook.
  3. Configurare Facebook Login come indicato di seguito:
    • Abilitare L'account di accesso OAuth client.
    • Abilitare l'account di accesso OAuth Web.
    • Impostare l'URI di reindirizzamento OAuth valido sull'URI dell'app Web servizio app, con /.auth/login/facebook/callback aggiunta.

Lo screenshot seguente illustra questa configurazione:

Facebook Login OAuth Settings

Per altre informazioni, vedi Registrare l'applicazione con Facebook.

Configurazione dell'autenticazione del servizio app Azure

Il processo di configurazione servizio app semplice autenticazione è il seguente:

  1. Nel portale di Azure passare all'app Web servizio app.

  2. Nel portale di Azure aprire il pannello Autenticazione/Autorizzazione ed eseguire la configurazione seguente:

    • servizio app l'autenticazione deve essere attivata.
    • L'azione da eseguire quando una richiesta non è autenticata deve essere impostata su Accedi con Facebook.

    Lo screenshot seguente illustra questa configurazione:

    App Service Web App Authentication Settings

L'app Web servizio app deve essere configurata anche per comunicare con l'app Facebook per abilitare il flusso di autenticazione. A tale scopo, è possibile selezionare il provider di identità Facebook e immettere i valori ID app e Segreto app dalle impostazioni dell'app Facebook nel Centro per sviluppatori di Facebook. Per altre informazioni, vedere Aggiungere informazioni su Facebook all'applicazione.

Xamarin.Forms Configurazione dell'applicazione

Il processo di configurazione dell'applicazione Xamarin.Forms di esempio è il seguente:

  1. Aprire la Xamarin.Forms soluzione.
  2. Aprire Constants.cs e aggiornare i valori delle costanti seguenti:
    • EndpointUri : il valore deve essere l'URL dell'account Azure Cosmos DB nel pannello Chiavi dell'account Azure Cosmos DB.
    • DatabaseName : il valore deve essere il nome del database di documenti.
    • CollectionName : il valore deve essere il nome della raccolta di database di documenti (in questo caso , UserItems).
    • ResourceTokenBrokerUrl: il valore deve essere l'URL dell'app Web del gestore di token di risorse nel pannello Panoramica dell'account servizio app.

Avvio dell'accesso

L'applicazione di esempio avvia il processo di accesso reindirizzando un browser a un URL del provider di identità, come illustrato nel codice di esempio seguente:

var auth = new Xamarin.Auth.WebRedirectAuthenticator(
  new Uri(Constants.ResourceTokenBrokerUrl + "/.auth/login/facebook"),
  new Uri(Constants.ResourceTokenBrokerUrl + "/.auth/login/done"));

In questo modo viene avviato un flusso di autenticazione OAuth tra app Azure Service e Facebook, che visualizza la pagina di accesso di Facebook:

Facebook Login

L'account di accesso può essere annullato premendo il pulsante Annulla in iOS o premendo il pulsante Indietro in Android, nel qual caso l'utente rimane non autenticato e l'interfaccia utente del provider di identità viene rimossa dalla schermata.

Recupero di un token di risorsa

Dopo l'autenticazione riuscita, viene generato l'evento WebRedirectAuthenticator.Completed . L'esempio di codice seguente illustra la gestione di questo evento:

auth.Completed += async (sender, e) =>
{
  if (e.IsAuthenticated && e.Account.Properties.ContainsKey("token"))
  {
    var easyAuthResponseJson = JsonConvert.DeserializeObject<JObject>(e.Account.Properties["token"]);
    var easyAuthToken = easyAuthResponseJson.GetValue("authenticationToken").ToString();

    // Call the ResourceBroker to get the resource token
    using (var httpClient = new HttpClient())
    {
      httpClient.DefaultRequestHeaders.Add("x-zumo-auth", easyAuthToken);
      var response = await httpClient.GetAsync(Constants.ResourceTokenBrokerUrl + "/api/resourcetoken/");
      var jsonString = await response.Content.ReadAsStringAsync();
      var tokenJson = JsonConvert.DeserializeObject<JObject>(jsonString);
      resourceToken = tokenJson.GetValue("token").ToString();
      UserId = tokenJson.GetValue("userid").ToString();

      if (!string.IsNullOrWhiteSpace(resourceToken))
      {
        client = new DocumentClient(new Uri(Constants.EndpointUri), resourceToken);
        ...
      }
      ...
    }
  }
};

Il risultato di un'autenticazione riuscita è un token di accesso, che è la proprietà disponibile AuthenticatorCompletedEventArgs.Account . Il token di accesso viene estratto e usato in una richiesta GET all'API del broker di token di resourcetoken risorse.

L'API resourcetoken usa il token di accesso per richiedere l'identità dell'utente da Facebook, che a sua volta viene usata per richiedere un token di risorsa da Azure Cosmos DB. Se esiste già un documento di autorizzazione valido per l'utente nel database di documenti, viene recuperato e viene restituito un documento JSON contenente il token di risorsa all'applicazione Xamarin.Forms . Se non esiste un documento di autorizzazione valido per l'utente, un utente e un'autorizzazione vengono creati nel database di documenti e il token della risorsa viene estratto dal documento di autorizzazione e restituito all'applicazione Xamarin.Forms in un documento JSON.

Nota

Un utente del database di documenti è una risorsa associata a un database di documenti e ogni database può contenere zero o più utenti. Un'autorizzazione per il database di documenti è una risorsa associata a un utente del database di documenti e ogni utente può contenere zero o più autorizzazioni. Una risorsa di autorizzazione fornisce l'accesso a un token di sicurezza richiesto dall'utente quando tenta di accedere a una risorsa, ad esempio un documento.

Se l'API resourcetoken viene completata correttamente, invierà il codice di stato HTTP 200 (OK) nella risposta, insieme a un documento JSON contenente il token di risorsa. I dati JSON seguenti mostrano un tipico messaggio di risposta riuscito:

{
  "id": "John Smithpermission",
  "token": "type=resource&ver=1&sig=zx6k2zzxqktzvuzuku4b7y==;a74aukk99qtwk8v5rxfrfz7ay7zzqfkbfkremrwtaapvavw2mrvia4umbi/7iiwkrrq+buqqrzkaq4pp15y6bki1u//zf7p9x/aefbvqvq3tjjqiffurfx+vexa1xarxkkv9rbua9ypfzr47xpp5vmxuvzbekkwq6txme0xxxbjhzaxbkvzaji+iru3xqjp05amvq1r1q2k+qrarurhmjzah/ha0evixazkve2xk1zu9u/jpyf1xrwbkxqpzebvqwma+hyyaazemr6qx9uz9be==;",
  "expires": 4035948,
  "userid": "John Smith"
}

Il WebRedirectAuthenticator.Completed gestore eventi legge la risposta dall'API resourcetoken ed estrae il token della risorsa e l'ID utente. Il token di risorsa viene quindi passato come argomento al DocumentClient costruttore, che incapsula l'endpoint, le credenziali e i criteri di connessione usati per accedere ad Azure Cosmos DB e viene usato per configurare ed eseguire richieste in Azure Cosmos DB. Il token di risorsa viene inviato con ogni richiesta per accedere direttamente a una risorsa e indica che viene concesso l'accesso in lettura/scrittura alla raccolta partizionata degli utenti autenticati.

Recupero di documenti

Il recupero di documenti che appartengono solo all'utente autenticato può essere ottenuto creando una query di documento che include l'ID dell'utente come chiave di partizione ed è illustrato nell'esempio di codice seguente:

var query = client.CreateDocumentQuery<TodoItem>(collectionLink,
                        new FeedOptions
                        {
                          MaxItemCount = -1,
                          PartitionKey = new PartitionKey(UserId)
                        })
          .Where(item => !item.Id.Contains("permission"))
          .AsDocumentQuery();
while (query.HasMoreResults)
{
  Items.AddRange(await query.ExecuteNextAsync<TodoItem>());
}

La query recupera in modo asincrono tutti i documenti appartenenti all'utente autenticato, dalla raccolta specificata e li inserisce in una List<TodoItem> raccolta per la visualizzazione.

Il CreateDocumentQuery<T> metodo specifica un Uri argomento che rappresenta l'insieme che deve essere sottoposto a query per i documenti e un FeedOptions oggetto . L'oggetto FeedOptions specifica che un numero illimitato di elementi può essere restituito dalla query e l'ID dell'utente come chiave di partizione. In questo modo, nel risultato vengono restituiti solo i documenti nella raccolta partizionata dell'utente.

Nota

Si noti che i documenti di autorizzazione creati dal gestore di token di risorse vengono archiviati nella stessa raccolta documenti dei documenti creati dall'applicazione Xamarin.Forms . Pertanto, la query del documento contiene una Where clausola che applica un predicato di filtro alla query sulla raccolta documenti. Questa clausola garantisce che i documenti di autorizzazione non vengano restituiti dalla raccolta documenti.

Per altre informazioni sul recupero di documenti da una raccolta documenti, vedere Recupero di documenti di raccolta documenti.

Inserimento di documenti

Prima di inserire un documento in una raccolta documenti, la TodoItem.UserId proprietà deve essere aggiornata con il valore usato come chiave di partizione, come illustrato nell'esempio di codice seguente:

item.UserId = UserId;
await client.CreateDocumentAsync(collectionLink, item);

In questo modo si garantisce che il documento venga inserito nella raccolta partizionata dell'utente.

Per altre informazioni sull'inserimento di un documento in una raccolta documenti, vedere Inserimento di un documento in una raccolta documenti.

Eliminazione di documenti

Il valore della chiave di partizione deve essere specificato quando si elimina un documento da una raccolta partizionata, come illustrato nell'esempio di codice seguente:

await client.DeleteDocumentAsync(UriFactory.CreateDocumentUri(Constants.DatabaseName, Constants.CollectionName, id),
                 new RequestOptions
                 {
                   PartitionKey = new PartitionKey(UserId)
                 });

Ciò garantisce che Azure Cosmos DB conosca la raccolta partizionata da cui eliminare il documento.

Per altre informazioni sull'eliminazione di un documento da una raccolta documenti, vedere Eliminazione di un documento da una raccolta documenti.

Riepilogo

Questo articolo ha illustrato come combinare il controllo di accesso con le raccolte partizionate, in modo che un utente possa accedere solo ai propri documenti di database di documenti in un'applicazione Xamarin.Forms . Se si specifica l'identità dell'utente come chiave di partizione, si garantisce che una raccolta partizionata possa archiviare solo i documenti per tale utente.