Authentifizieren von Benutzern mit einer Azure Cosmos DB-Dokumentdatenbank und Xamarin.Forms

Azure Cosmos DB-Dokumentdatenbanken unterstützen partitionierte Sammlungen, die mehrere Server und Partitionen umfassen können und gleichzeitig unbegrenzten Speicher und Durchsatz unterstützen. In diesem Artikel wird erläutert, wie Sie die Zugriffssteuerung mit partitionierten Sammlungen kombinieren, sodass ein Benutzer nur auf seine eigenen Dokumente in einer Xamarin.Forms Anwendung zugreifen kann.

Übersicht

Beim Erstellen einer partitionierten Auflistung muss ein Partitionsschlüssel angegeben werden, und Dokumente mit demselben Partitionsschlüssel werden in derselben Partition gespeichert. Daher führt die Angabe der Identität des Benutzers als Partitionsschlüssel zu einer partitionierten Sammlung, die nur Dokumente für diesen Benutzer speichert. Dadurch wird auch sichergestellt, dass die Azure Cosmos DB-Dokumentdatenbank skaliert wird, wenn sich die Anzahl der Benutzer und Elemente erhöht.

Zugriff muss jeder Sammlung gewährt werden, und das Azure Cosmos DB für NoSQL-Zugriffssteuerungsmodell definiert zwei Arten von Zugriffskonstrukten:

  • Hauptschlüssel ermöglichen den vollständigen Administratorzugriff auf alle Ressourcen in einem Azure Cosmos DB-Konto und werden erstellt, wenn ein Azure Cosmos DB-Konto erstellt wird.
  • Ressourcentoken erfassen die Beziehung zwischen dem Benutzer einer Datenbank und der Berechtigung, die der Benutzer für eine bestimmte Azure Cosmos DB-Ressource hat, z. B. eine Sammlung oder ein Dokument.

Wenn Sie einen Hauptschlüssel verfügbar machen, wird ein Azure Cosmos DB-Konto zur Möglichkeit einer böswilligen oder fahrlässigen Verwendung geöffnet. Azure Cosmos DB-Ressourcentoken bieten jedoch einen sicheren Mechanismus, mit dem Clients bestimmte Ressourcen in einem Azure Cosmos DB-Konto gemäß den erteilten Berechtigungen lesen, schreiben und löschen können.

Ein typischer Ansatz zum Anfordern, Generieren und Bereitstellen von Ressourcentoken an eine mobile Anwendung besteht darin, einen Ressourcentokenbroker zu verwenden. Das folgende Diagramm zeigt eine allgemeine Übersicht darüber, wie die Beispielanwendung einen Ressourcentokenbroker zum Verwalten des Zugriffs auf die Dokumentdatenbankdaten verwendet:

Dokumentdatenbankauthentifizierungsprozess

Der Ressourcentokenbroker ist ein in Azure-App Dienst gehosteter Mid-Tier-Web-API-Dienst, der den Hauptschlüssel des Azure Cosmos DB-Kontos besitzt. Die Beispielanwendung verwendet den Ressourcentokenbroker, um den Zugriff auf die Dokumentdatenbankdaten wie folgt zu verwalten:

  1. Bei der Anmeldung kontaktiert die Xamarin.Forms Anwendung Azure-App Dienst, um einen Authentifizierungsfluss zu initiieren.
  2. Azure-App Dienst führt einen OAuth-Authentifizierungsfluss mit Facebook aus. Nach Abschluss des Authentifizierungsflusses empfängt die Xamarin.Forms Anwendung ein Zugriffstoken.
  3. Die Xamarin.Forms Anwendung verwendet das Zugriffstoken, um ein Ressourcentoken vom Ressourcentokenbroker anzufordern.
  4. Der Ressourcentokenbroker verwendet das Zugriffstoken, um die Identität des Benutzers von Facebook anzufordern. Die Identität des Benutzers wird dann verwendet, um ein Ressourcentoken von Azure Cosmos DB anzufordern, das verwendet wird, um Lese-/Schreibzugriff auf die partitionierte Sammlung des authentifizierten Benutzers zu gewähren.
  5. Die Xamarin.Forms Anwendung verwendet das Ressourcentoken, um direkt auf Azure Cosmos DB-Ressourcen mit den vom Ressourcentoken definierten Berechtigungen zuzugreifen.

Hinweis

Wenn das Ressourcentoken abläuft, erhalten nachfolgende Dokumentdatenbankanforderungen eine 401 nicht autorisierte Ausnahme. Zu diesem Zeitpunkt Xamarin.Forms sollten Anwendungen die Identität neu einrichten und ein neues Ressourcentoken anfordern.

Weitere Informationen zur Azure Cosmos DB-Partitionierung finden Sie unter Partitionierung und Skalierung in Azure Cosmos DB. Weitere Informationen zur Zugriffssteuerung von Azure Cosmos DB finden Sie unter Sichern des Zugriffs auf Azure Cosmos DB-Daten und Zugriffssteuerung im Azure Cosmos DB für NoSQL.

Setup

Der Prozess für die Integration des Ressourcentokenbrokers in eine Xamarin.Forms Anwendung lautet wie folgt:

  1. Erstellen Sie ein Azure Cosmos DB-Konto, das die Zugriffssteuerung verwendet. Weitere Informationen finden Sie unter Azure Cosmos DB-Konfiguration.
  2. Erstellen Sie einen Azure-App Dienst zum Hosten des Ressourcentokenbrokers. Weitere Informationen finden Sie unter Azure-App Dienstkonfiguration.
  3. Erstellen Sie eine Facebook-App, um die Authentifizierung durchzuführen. Weitere Informationen finden Sie unter Facebook App Configuration.
  4. Konfigurieren Sie den Azure-App-Dienst, um die einfache Authentifizierung mit Facebook durchzuführen. Weitere Informationen finden Sie unter Azure-App Dienstauthentifizierungskonfiguration.
  5. Konfigurieren Sie die Beispielanwendung für die Xamarin.Forms Kommunikation mit Azure-App Service und Azure Cosmos DB. Weitere Informationen finden Sie unter Xamarin.Forms Anwendungskonfiguration.

Hinweis

Wenn Sie kein Azure-Abonnement besitzen, erstellen Sie ein kostenloses Konto, bevor Sie beginnen.

Azure Cosmos DB-Konfiguration

Der Prozess zum Erstellen eines Azure Cosmos DB-Kontos, das die Zugriffssteuerung verwendet, lautet wie folgt:

  1. Erstellung eines Azure Cosmos DB-Kontos. Weitere Informationen finden Sie unter Erstellen eines Azure Cosmos DB-Kontos.
  2. Erstellen Sie im Azure Cosmos DB-Konto eine neue Sammlung mit dem Namen UserItems, die einen Partitionsschlüssel angibt /userid.

Azure-App Dienstkonfiguration

Der Prozess zum Hosten des Ressourcentokenbrokers in Azure-App Service lautet wie folgt:

  1. Erstellen Sie in der Azure-Portal eine neue App Service-Web-App. Weitere Informationen finden Sie unter Erstellen einer Web-App in einer App Service-Umgebung.

  2. Öffnen Sie im Azure-Portal das Blatt "App Einstellungen" für die Web-App, und fügen Sie die folgenden Einstellungen hinzu:

    • accountUrl – Der Wert sollte die Azure Cosmos DB-Konto-URL aus dem Blatt Schlüssel des Azure Cosmos DB-Kontos sein.
    • accountKey – Der Wert sollte der Azure Cosmos DB-Hauptschlüssel (primär oder sekundär) aus dem Schlüsselblatt des Azure Cosmos DB-Kontos sein.
    • databaseId – Der Wert sollte der Name der Azure Cosmos DB-Datenbank sein.
    • collectionId – Der Wert sollte der Name der Azure Cosmos DB-Sammlung sein (in diesem Fall UserItems).
    • hostUrl – Der Wert sollte die URL der Web-App aus dem Blatt "Übersicht" des App Service-Kontos sein.

    Der folgende Screenshot zeigt diese Konfiguration:

    App Web App-Einstellungen

  3. Veröffentlichen Sie die Ressourcentokenbrokerlösung in der Azure-App Service Web App.

Facebook-App-Konfiguration

Der Prozess zum Erstellen einer Facebook-App zur Authentifizierung lautet wie folgt:

  1. Erstellen Sie eine Facebook-App. Weitere Informationen finden Sie unter Registrieren und Konfigurieren einer App im Facebook Developer Center.
  2. Fügen Sie das Facebook Login-Produkt zur App hinzu. Weitere Informationen finden Sie unter Hinzufügen der Facebook-Anmeldung zu Ihrer App oder Website im Facebook Developer Center.
  3. Konfigurieren Sie Facebook Login wie folgt:
    • Aktivieren Sie die Client-OAuth-Anmeldung.
    • Web OAuth-Anmeldung aktivieren.
    • Legen Sie den gültigen OAuth-Umleitungs-URI auf den URI der App-Dienst-Web-App fest, mit /.auth/login/facebook/callback angefügt.

Der folgende Screenshot zeigt diese Konfiguration:

Facebook Login OAuth Einstellungen

Weitere Informationen finden Sie unter Registrieren Ihrer Anwendung bei Facebook.

Azure-App Dienstauthentifizierungskonfiguration

Der Prozess zum Konfigurieren der einfachen Authentifizierung von App Service lautet wie folgt:

  1. Navigieren Sie im Azure-Portal zur App Service-Web-App.

  2. Öffnen Sie im Azure-Portal das Blatt "Authentifizierung/Autorisierung", und führen Sie die folgende Konfiguration aus:

    • Die App-Dienstauthentifizierung sollte aktiviert sein.
    • Die Aktion, die ausgeführt werden soll, wenn eine Anforderung nicht authentifiziert wird, sollte bei Facebook auf "Anmelden" festgelegt werden.

    Der folgende Screenshot zeigt diese Konfiguration:

    App Service Web App-Authentifizierung Einstellungen

Die App Service-Web-App sollte auch für die Kommunikation mit der Facebook-App konfiguriert werden, um den Authentifizierungsfluss zu aktivieren. Dazu können Sie den Facebook-Identitätsanbieter auswählen und die Werte " App-ID " und "App Secret " aus den Facebook-App-Einstellungen im Facebook Developer Center eingeben. Weitere Informationen finden Sie unter Hinzufügen von Facebook-Informationen zu Ihrer Anwendung.

Xamarin.Forms Anwendungskonfiguration

Der Prozess zum Konfigurieren der Xamarin.Forms Beispielanwendung lautet wie folgt:

  1. Öffnen Sie die Xamarin.Forms Lösung.
  2. Öffnen und aktualisieren Sie Constants.cs die Werte der folgenden Konstanten:
    • EndpointUri – Der Wert sollte die Azure Cosmos DB-Konto-URL aus dem Blatt Schlüssel des Azure Cosmos DB-Kontos sein.
    • DatabaseName – Der Wert sollte der Name der Dokumentdatenbank sein.
    • CollectionName – Der Wert sollte der Name der Dokumentdatenbanksammlung (in diesem Fall) UserItemssein.
    • ResourceTokenBrokerUrl – Der Wert sollte die URL der Web-App des Ressourcentokenbrokers aus dem Blatt "Übersicht" des App Service-Kontos sein.

Initiieren der Anmeldung

Die Beispielanwendung initiiert den Anmeldevorgang durch Umleiten eines Browsers an eine Identitätsanbieter-URL, wie im folgenden Beispielcode veranschaulicht:

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

Dadurch wird ein OAuth-Authentifizierungsfluss zwischen Azure-App Service und Facebook initiiert, der die Facebook-Anmeldeseite anzeigt:

Facebook-Anmeldung

Die Anmeldung kann durch Drücken der Schaltfläche "Abbrechen" unter iOS oder durch Drücken der Schaltfläche "Zurück" auf Android abgebrochen werden. In diesem Fall wird der Benutzer erneut Standard nicht authentifiziert, und die Benutzeroberfläche des Identitätsanbieters wird vom Bildschirm entfernt.

Abrufen eines Ressourcentokens

Nach erfolgreicher Authentifizierung wird das WebRedirectAuthenticator.Completed Ereignis ausgelöst. Im folgenden Codebeispiel wird die Behandlung dieses Ereignisses veranschaulicht:

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);
        ...
      }
      ...
    }
  }
};

Das Ergebnis einer erfolgreichen Authentifizierung ist ein Zugriffstoken, das verfügbar AuthenticatorCompletedEventArgs.Account ist. Das Zugriffstoken wird extrahiert und in einer GET-Anforderung an die API des Ressourcentokenbrokers resourcetoken verwendet.

Die resourcetoken API verwendet das Zugriffstoken, um die Identität des Benutzers von Facebook anzufordern, die wiederum verwendet wird, um ein Ressourcentoken von Azure Cosmos DB anzufordern. Wenn bereits ein gültiges Berechtigungsdokument für den Benutzer in der Dokumentdatenbank vorhanden ist, wird es abgerufen, und ein JSON-Dokument, das das Ressourcentoken enthält, wird an die Xamarin.Forms Anwendung zurückgegeben. Wenn kein gültiges Berechtigungsdokument für den Benutzer vorhanden ist, wird ein Benutzer und eine Berechtigung in der Dokumentdatenbank erstellt, und das Ressourcentoken wird aus dem Berechtigungsdokument extrahiert und an die Xamarin.Forms Anwendung in einem JSON-Dokument zurückgegeben.

Hinweis

Ein Dokumentdatenbankbenutzer ist eine Ressource, die einer Dokumentdatenbank zugeordnet ist, und jede Datenbank kann null oder mehr Benutzer enthalten. Eine Dokumentdatenbankberechtigung ist eine Ressource, die einem Dokumentdatenbankbenutzer zugeordnet ist, und jeder Benutzer kann null oder mehr Berechtigungen enthalten. Eine Berechtigungsressource bietet Zugriff auf ein Sicherheitstoken, das der Benutzer benötigt, wenn er versucht, auf eine Ressource wie ein Dokument zuzugreifen.

Wenn die resourcetoken API erfolgreich abgeschlossen wurde, sendet sie den HTTP-Statuscode 200 (OK) in der Antwort zusammen mit einem JSON-Dokument, das das Ressourcentoken enthält. Die folgenden JSON-Daten zeigen eine typische erfolgreiche Antwortnachricht:

{
  "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"
}

Der WebRedirectAuthenticator.Completed Ereignishandler liest die Antwort aus der resourcetoken API und extrahiert das Ressourcentoken und die Benutzer-ID. Das Ressourcentoken wird dann als Argument an den DocumentClient Konstruktor übergeben, der den Endpunkt, die Anmeldeinformationen und die Verbindungsrichtlinie für den Zugriff auf Azure Cosmos DB kapselt und zum Konfigurieren und Ausführen von Anforderungen für Azure Cosmos DB verwendet wird. Das Ressourcentoken wird mit jeder Anforderung gesendet, um direkt auf eine Ressource zuzugreifen, und gibt an, dass Lese-/Schreibzugriff auf die partitionierte Sammlung der authentifizierten Benutzer gewährt wird.

Abrufen von Dokumenten

Das Abrufen von Dokumenten, die nur zum authentifizierten Benutzer gehören, kann erreicht werden, indem eine Dokumentabfrage erstellt wird, die die ID des Benutzers als Partitionsschlüssel enthält, und im folgenden Codebeispiel veranschaulicht wird:

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>());
}

Die Abfrage ruft asynchron alle Dokumente ab, die dem authentifizierten Benutzer gehören, aus der angegebenen Auflistung und platziert sie in einer List<TodoItem> Sammlung zur Anzeige.

Die CreateDocumentQuery<T> Methode gibt ein Uri Argument an, das die Auflistung darstellt, die für Dokumente und ein FeedOptions Objekt abgefragt werden soll. Das FeedOptions Objekt gibt an, dass eine unbegrenzte Anzahl von Elementen von der Abfrage und die ID des Benutzers als Partitionsschlüssel zurückgegeben werden kann. Dadurch wird sichergestellt, dass nur Dokumente in der partitionierten Sammlung des Benutzers im Ergebnis zurückgegeben werden.

Hinweis

Beachten Sie, dass Berechtigungsdokumente, die vom Ressourcentokenbroker erstellt werden, in derselben Dokumentsammlung wie die von der Xamarin.Forms Anwendung erstellten Dokumente gespeichert werden. Daher enthält die Dokumentabfrage eine Where Klausel, die ein Filter-Prädikat auf die Abfrage für die Dokumentsammlung anwendet. Diese Klausel stellt sicher, dass Berechtigungsdokumente nicht aus der Dokumentsammlung zurückgegeben werden.

Weitere Informationen zum Abrufen von Dokumenten aus einer Dokumentsammlung finden Sie unter Abrufen von Dokumentensammlungsdokumenten.

Einfügen von Dokumenten

Vor dem Einfügen eines Dokuments in eine Dokumentauflistung sollte die TodoItem.UserId Eigenschaft mit dem Wert aktualisiert werden, der als Partitionsschlüssel verwendet wird, wie im folgenden Codebeispiel veranschaulicht:

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

Dadurch wird sichergestellt, dass das Dokument in die partitionierte Sammlung des Benutzers eingefügt wird.

Weitere Informationen zum Einfügen eines Dokuments in eine Dokumentsammlung finden Sie unter Einfügen eines Dokuments in eine Dokumentsammlung.

Löschen von Dokumenten

Der Partitionsschlüsselwert muss beim Löschen eines Dokuments aus einer partitionierten Auflistung angegeben werden, wie im folgenden Codebeispiel veranschaulicht:

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

Dadurch wird sichergestellt, dass Azure Cosmos DB weiß, aus welcher partitionierten Sammlung das Dokument gelöscht werden soll.

Weitere Informationen zum Löschen eines Dokuments aus einer Dokumentsammlung finden Sie unter Löschen eines Dokuments aus einer Dokumentsammlung.

Zusammenfassung

In diesem Artikel wird erläutert, wie Sie die Zugriffssteuerung mit partitionierten Sammlungen kombinieren, sodass ein Benutzer nur auf eigene Dokumentdatenbankdokumente in einer Xamarin.Forms Anwendung zugreifen kann. Wenn Sie die Identität des Benutzers als Partitionsschlüssel angeben, wird sichergestellt, dass eine partitionierte Sammlung nur Dokumente für diesen Benutzer speichern kann.