In this article

Authenticating Users with an Azure Cosmos DB Document Database

In this article

Azure Cosmos DB document databases support partitioned collections, which can span multiple servers and partitions, while supporting unlimited storage and throughput. This article explains how to combine access control with partitioned collections, so that a user can only access their own documents in a Xamarin.Forms application.

Overview

A partition key must be specified when creating a partitioned collection, and documents with the same partition key will be stored in the same partition. Therefore, specifying the user's identity as a partition key will result in a partitioned collection that will only store documents for that user. This also ensures that the Azure Cosmos DB document database will scale as the number of users and items increase.

Access must be granted to any collection, and the SQL API access control model defines two types of access constructs:

Master keys enable full administrative access to all resources within a Cosmos DB account, and are created when a Cosmos DB account is created.

Resource tokens capture the relationship between the user of a database and the permission the user has for a specific Cosmos DB resource, such as a collection or a document.

Exposing a master key opens a Cosmos DB account to the possibility of malicious or negligent use. However, Azure Cosmos DB resource tokens provide a safe mechanism for allowing clients to read, write, and delete specific resources in an Azure Cosmos DB account according to the granted permissions.

A typical approach to requesting, generating, and delivering resource tokens to a mobile application is to use a resource token broker. The following diagram shows a high-level overview of how the sample application uses a resource token broker to manage access to the document database data:

The resource token broker is a mid-tier Web API service, hosted in Azure App Service, which possesses the master key of the Cosmos DB account. The sample application uses the resource token broker to manage access to the document database data as follows:

On login, the Xamarin.Forms application contacts Azure App Service to initiate an authentication flow.

Azure App Service performs an OAuth authentication flow with Facebook. After the authentication flow completes, the Xamarin.Forms application receives an access token.

The Xamarin.Forms application uses the access token to request a resource token from the resource token broker.

The resource token broker uses the access token to request the user's identity from Facebook. The user's identity is then used to request a resource token from Cosmos DB, which is used to grant read/write access to the authenticated user's partitioned collection.

The Xamarin.Forms application uses the resource token to directly access Cosmos DB resources with the permissions defined by the resource token.

Note

When the resource token expires, subsequent document database requests will receive a 401 unauthorized exception. At this point, Xamarin.Forms applications should re-establish the identity and request a new resource token.

Azure App Service Authentication Configuration

The process for configuring App Service easy authentication is as follows:

In the Azure Portal, navigate to the App Service web app.

In the Azure Portal, open the Authentication / Authorization blade and perform the following configuration:

App Service Authentication should be turned on.

The action to take when a request is not authenticated should be set to Login in with Facebook.

The following screenshot demonstrates this configuration:

The App Service web app should also be configured to communicate with the Facebook app to enable the authentication flow. This can be accomplished by selecting the Facebook identity provider, and entering the App ID and App Secret values from the Facebook app settings on the Facebook Developer Center. For more information, see Add Facebook information to your application.

Xamarin.Forms Application Configuration

The process for configuring the Xamarin.Forms sample application is as follows:

Open the Xamarin.Forms solution.

Open Constants.cs and update the values of the following constants:

EndpointUri – the value should be the Cosmos DB account URL from the Keys blade of the Cosmos DB account.

DatabaseName – the value should be the name of the document database.

CollectionName – the value should be the name of the document database collection (in this case, UserItems).

ResourceTokenBrokerUrl – the value should be the URL of the resource token broker web app from the Overview blade of the App Service account.

Initiating Login

The sample application initiates the login process by using Xamarin.Auth to redirect a browser to an identity provider URL, as demonstrated in the following example code:

This causes an OAuth authentication flow to be initiated between Azure App Service and Facebook, which displays the Facebook login page:

The login can be cancelled by pressing the Cancel button on iOS or by pressing the Back button on Android, in which case the user remains unauthenticated and the identity provider user interface is removed from the screen.

The result of a successful authentication is an access token, which is available AuthenticatorCompletedEventArgs.Account property. The access token is extracted and used in a GET request to the resource token broker's resourcetoken API.

The resourcetoken API uses the access token to request the user's identity from Facebook, which in turn is used to request a resource token from Cosmos DB. If a valid permission document already exists for the user in the document database, it's retrieved and a JSON document containing the resource token is returned to the Xamarin.Forms application. If a valid permission document doesn't exist for the user, a user and permission is created in the document database, and the resource token is extracted from the permission document and returned to the Xamarin.Forms application in a JSON document.

Note

A document database user is a resource associated with a document database, and each database may contain zero or more users. A document database permission is a resource associated with a document database user, and each user may contain zero or more permissions. A permission resource provides access to a security token that the user requires when attempting to access a resource such as a document.

If the resourcetoken API successfully completes, it will send HTTP status code 200 (OK) in the response, along with a JSON document containing the resource token. The following JSON data shows a typical successful response message:

The WebRedirectAuthenticator.Completed event handler reads the response from the resourcetoken API and extracts the resource token and the user id. The resource token is then passed as an argument to the DocumentClient constructor, which encapsulates the endpoint, credentials, and connection policy used to access Cosmos DB, and is used to configure and execute requests against Cosmos DB. The resource token is sent with each request to directly access a resource, and indicates that read/write access to the authenticated users' partitioned collection is granted.

Retrieving Documents

Retrieving documents that only belong to the authenticated user can be achieved by creating a document query that includes the user's id as a partition key, and is demonstrated in the following code example:

The query asynchronously retrieves all the documents belonging to the authenticated user, from the specified collection, and places them in a List<TodoItem> collection for display.

The CreateDocumentQuery<T> method specifies a Uri argument that represents the collection that should be queried for documents, and a FeedOptions object. The FeedOptions object specifies that an unlimited number of items can be returned by the query, and the user's id as a partition key. This ensures that only documents in the user's partitioned collection are returned in the result.

Note

Note that permission documents, which are created by the resource token broker, are stored in the same document collection as the documents created by the Xamarin.Forms application. Therefore, the document query contains a Where clause that applies a filtering predicate to the query against the document collection. This clause ensures that permission documents aren't returned from the document collection.

Summary

This article explained how to combine access control with partitioned collections, so that a user can only access their own document database documents in a Xamarin.Forms application. Specifying the user's identity as a partition key ensures that a partitioned collection can only store documents for that user.