Authentifier les utilisateurs avec une base de données de documents Azure Cosmos DB et Xamarin.Forms
Les bases de données de documents Azure Cosmos DB prennent en charge les collections partitionnée, qui peuvent s’étendre sur plusieurs serveurs et partitions, tout en prenant en charge un stockage et un débit illimités. Cet article explique comment combiner le contrôle d’accès avec des collections partitionnés afin qu’un utilisateur puisse accéder uniquement à ses propres documents dans une Xamarin.Forms application.
Vue d’ensemble
Une clé de partition doit être spécifiée lors de la création d’une collection partitionnée, et les documents avec la même clé de partition sont stockés dans la même partition. Par conséquent, la spécification de l’identité de l’utilisateur en tant que clé de partition entraîne une collection partitionnée qui stocke uniquement les documents de cet utilisateur. Cela garantit également que la base de données de documents Azure Cosmos DB sera mise à l’échelle à mesure que le nombre d’utilisateurs et d’éléments augmente.
L’accès doit être accordé à n’importe quelle collection et le modèle de contrôle d’accès Azure Cosmos DB pour NoSQL définit deux types de constructions d’accès :
- Les clés principales permettent un accès administratif complet à toutes les ressources au sein d’un compte Azure Cosmos DB et sont créées lors de la création d’un compte Azure Cosmos DB.
- Les jetons de ressource capturent la relation entre l’utilisateur d’une base de données et l’autorisation dont l’utilisateur dispose pour une ressource Azure Cosmos DB spécifique, telle qu’une collection ou un document.
L’exposition d’une clé principale ouvre un compte Azure Cosmos DB à la possibilité d’une utilisation malveillante ou négligente. Toutefois, les jetons de ressource Azure Cosmos DB fournissent un mécanisme sécurisé permettant aux clients de lire, d’écrire et de supprimer des ressources spécifiques dans un compte Azure Cosmos DB en fonction des autorisations accordées.
Une approche classique de la demande, de la génération et de la remise de jetons de ressources à une application mobile consiste à utiliser un répartiteur de jetons de ressource. Le diagramme suivant présente une vue d’ensemble générale de la façon dont l’exemple d’application utilise un répartiteur de jetons de ressources pour gérer l’accès aux données de base de données de documents :
Le répartiteur de jetons de ressource est un service d’API web de niveau intermédiaire, hébergé dans Azure App Service, qui possède la clé principale du compte Azure Cosmos DB. L’exemple d’application utilise le répartiteur de jetons de ressource pour gérer l’accès aux données de base de données de documents comme suit :
- Lors de la connexion, l’application Xamarin.Forms contacte Azure App Service pour lancer un flux d’authentification.
- Azure App Service effectue un flux d’authentification OAuth avec Facebook. Une fois le flux d’authentification terminé, l’application Xamarin.Forms reçoit un jeton d’accès.
- L’application Xamarin.Forms utilise le jeton d’accès pour demander un jeton de ressource auprès du répartiteur de jetons de ressource.
- Le répartiteur de jetons de ressource utilise le jeton d’accès pour demander l’identité de l’utilisateur auprès de Facebook. L’identité de l’utilisateur est ensuite utilisée pour demander un jeton de ressource auprès d’Azure Cosmos DB, qui est utilisé pour accorder l’accès en lecture/écriture à la collection partitionnée de l’utilisateur authentifié.
- L’application Xamarin.Forms utilise le jeton de ressource pour accéder directement aux ressources Azure Cosmos DB avec les autorisations définies par le jeton de ressource.
Remarque
Lorsque le jeton de ressource expire, les demandes de base de données de documents suivantes reçoivent une exception non autorisée 401. À ce stade, Xamarin.Forms les applications doivent rétablir l’identité et demander un nouveau jeton de ressource.
Pour plus d’informations sur le partitionnement Azure Cosmos DB, consultez Comment partitionner et mettre à l’échelle dans Azure Cosmos DB. Pour plus d’informations sur le contrôle d’accès Azure Cosmos DB, consultez Sécurisation de l’accès aux données Azure Cosmos DB et contrôle d’accès dans Azure Cosmos DB pour NoSQL.
Programme d’installation
Le processus d’intégration du répartiteur de jetons de ressource dans une Xamarin.Forms application est le suivant :
- Créez un compte Azure Cosmos DB qui utilisera le contrôle d’accès. Pour plus d’informations, consultez Configuration d’Azure Cosmos DB.
- Créez un service Azure App Service pour héberger le répartiteur de jetons de ressource. Pour plus d’informations, consultez Azure App Service Configuration.
- Créez une application Facebook pour effectuer l’authentification. Pour plus d’informations, consultez Facebook App Configuration.
- Configurez Azure App Service pour effectuer une authentification simple avec Facebook. Pour plus d’informations, consultez Configuration de l’authentification Azure App Service.
- Configurez l’exemple Xamarin.Forms d’application pour communiquer avec Azure App Service et Azure Cosmos DB. Pour plus d’informations, consultez Xamarin.Forms Configuration de l’application.
Remarque
Si vous n’avez pas d’abonnement Azure, créez un compte gratuit avant de commencer.
Configuration d’Azure Cosmos DB
Le processus de création d’un compte Azure Cosmos DB qui utilisera le contrôle d’accès est le suivant :
- Créez un compte Azure Cosmos DB. Pour plus d’informations, consultez Créer un compte Azure Cosmos DB.
- Dans le compte Azure Cosmos DB, créez une collection nommée
UserItems
, en spécifiant une clé de partition de/userid
.
Configuration d’Azure App Service
Le processus d’hébergement du répartiteur de jetons de ressource dans Azure App Service est le suivant :
Dans le Portail Azure, créez une application web App Service. Pour plus d’informations, consultez Créer une application web dans un environnement App Service.
Dans le Portail Azure, ouvrez le panneau App Paramètres pour l’application web, puis ajoutez les paramètres suivants :
accountUrl
: la valeur doit être l’URL du compte Azure Cosmos DB à partir du panneau Clés du compte Azure Cosmos DB.accountKey
: la valeur doit être la clé principale Azure Cosmos DB (primaire ou secondaire) à partir du panneau Clés du compte Azure Cosmos DB.databaseId
: la valeur doit être le nom de la base de données Azure Cosmos DB.collectionId
: la valeur doit être le nom de la collection Azure Cosmos DB (dans ce cas,UserItems
).hostUrl
: la valeur doit être l’URL de l’application web à partir du panneau Vue d’ensemble du compte App Service.
La capture d’écran suivante illustre cette configuration :
Publiez la solution de répartiteur de jetons de ressources sur l’application web Azure App Service.
Configuration de l’application Facebook
Le processus de création d’une application Facebook pour effectuer l’authentification est le suivant :
- Créez une application Facebook. Pour plus d’informations, consultez Inscrire et configurer une application dans le Centre de développement Facebook.
- Ajoutez le produit Facebook Login à l’application. Pour plus d’informations, consultez Ajouter une connexion Facebook à votre application ou site web dans le Centre de développement Facebook.
- Configurez la connexion Facebook comme suit :
- Activez la connexion OAuth du client.
- Activez la connexion OAuth web.
- Définissez l’URI de redirection OAuth valide sur l’URI de l’application web App Service, avec
/.auth/login/facebook/callback
l’ajout.
La capture d’écran suivante illustre cette configuration :
Pour plus d’informations, consultez Inscrire votre application auprès de Facebook.
Configuration de l’authentification Azure App Service
Le processus de configuration de l’authentification simple App Service est le suivant :
Dans le portail Azure, accédez à l’application web App Service.
Dans le portail Azure, ouvrez le panneau Authentification/Autorisation et effectuez la configuration suivante :
- L’authentification App Service doit être activée.
- L’action à entreprendre lorsqu’une demande n’est pas authentifiée doit être définie sur Connexion avec Facebook.
La capture d’écran suivante illustre cette configuration :
L’application web App Service doit également être configurée pour communiquer avec l’application Facebook pour activer le flux d’authentification. Pour ce faire, sélectionnez le fournisseur d’identité Facebook et entrez l’ID d’application et les valeurs secret de l’application à partir des paramètres de l’application Facebook dans le Centre de développement Facebook. Pour plus d’informations, consultez Ajouter des informations Facebook à votre application.
Xamarin.Forms Configuration de l’application
Le processus de configuration de l’exemple d’application Xamarin.Forms est le suivant :
- Ouvrez la Xamarin.Forms solution.
- Ouvrez
Constants.cs
et mettez à jour les valeurs des constantes suivantes :EndpointUri
: la valeur doit être l’URL du compte Azure Cosmos DB à partir du panneau Clés du compte Azure Cosmos DB.DatabaseName
: la valeur doit être le nom de la base de données de document.CollectionName
: la valeur doit être le nom de la collection de bases de données de documents (dans ce cas,UserItems
).ResourceTokenBrokerUrl
: la valeur doit être l’URL de l’application web du répartiteur de jetons de ressources à partir du panneau Vue d’ensemble du compte App Service.
Lancement de la connexion
L’exemple d’application lance le processus de connexion en redirigeant un navigateur vers une URL du fournisseur d’identité, comme illustré dans l’exemple de code suivant :
var auth = new Xamarin.Auth.WebRedirectAuthenticator(
new Uri(Constants.ResourceTokenBrokerUrl + "/.auth/login/facebook"),
new Uri(Constants.ResourceTokenBrokerUrl + "/.auth/login/done"));
Cela entraîne l’initial d’un flux d’authentification OAuth entre Azure App Service et Facebook, qui affiche la page de connexion Facebook :
La connexion peut être annulée en appuyant sur le bouton Annuler sur iOS ou en appuyant sur le bouton Précédent sur Android, auquel cas l’utilisateur reste non authentifié et l’interface utilisateur du fournisseur d’identité est supprimée de l’écran.
Obtention d’un jeton de ressource
Après l’authentification réussie, l’événement WebRedirectAuthenticator.Completed
se déclenche. L’exemple de code suivant illustre la gestion de cet événement :
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);
...
}
...
}
}
};
Le résultat d’une authentification réussie est un jeton d’accès, qui est disponible AuthenticatorCompletedEventArgs.Account
. Le jeton d’accès est extrait et utilisé dans une requête GET à l’API du répartiteur de jetons de resourcetoken
ressource.
L’API resourcetoken
utilise le jeton d’accès pour demander l’identité de l’utilisateur à partir de Facebook, qui à son tour est utilisée pour demander un jeton de ressource auprès d’Azure Cosmos DB. Si un document d’autorisation valide existe déjà pour l’utilisateur dans la base de données de documents, il est récupéré et un document JSON contenant le jeton de ressource est retourné à l’application Xamarin.Forms . Si un document d’autorisation valide n’existe pas pour l’utilisateur, un utilisateur et une autorisation sont créés dans la base de données de document, et le jeton de ressource est extrait du document d’autorisation et retourné à l’application Xamarin.Forms dans un document JSON.
Remarque
Un utilisateur de base de données de documents est une ressource associée à une base de données de documents, et chaque base de données peut contenir zéro ou plusieurs utilisateurs. Une autorisation de base de données de documents est une ressource associée à un utilisateur de base de données de documents, et chaque utilisateur peut contenir zéro ou plusieurs autorisations. Une ressource d’autorisation fournit l’accès à un jeton de sécurité requis par l’utilisateur lors de la tentative d’accès à une ressource telle qu’un document.
Si l’API resourcetoken
se termine correctement, elle envoie le code d’état HTTP 200 (OK) dans la réponse, ainsi qu’un document JSON contenant le jeton de ressource. Les données JSON suivantes illustrent un message de réponse réussi classique :
{
"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"
}
Le WebRedirectAuthenticator.Completed
gestionnaire d’événements lit la réponse de l’API resourcetoken
et extrait le jeton de ressource et l’ID utilisateur. Le jeton de ressource est ensuite passé en tant qu’argument au DocumentClient
constructeur, qui encapsule le point de terminaison, les informations d’identification et la stratégie de connexion utilisés pour accéder à Azure Cosmos DB et est utilisé pour configurer et exécuter des requêtes sur Azure Cosmos DB. Le jeton de ressource est envoyé avec chaque demande d’accès direct à une ressource et indique que l’accès en lecture/écriture à la collection partitionnée des utilisateurs authentifiés est accordé.
Récupération de documents
La récupération de documents qui appartiennent uniquement à l’utilisateur authentifié peut être obtenue en créant une requête de document qui inclut l’ID de l’utilisateur comme clé de partition, et est illustrée dans l’exemple de code suivant :
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 requête récupère de façon asynchrone tous les documents appartenant à l’utilisateur authentifié, à partir de la collection spécifiée et les place dans une List<TodoItem>
collection à afficher.
La CreateDocumentQuery<T>
méthode spécifie un Uri
argument qui représente la collection qui doit être interrogée pour les documents et un FeedOptions
objet. L’objet FeedOptions
spécifie qu’un nombre illimité d’éléments peut être retourné par la requête et l’ID de l’utilisateur comme clé de partition. Cela garantit que seuls les documents de la collection partitionnée de l’utilisateur sont retournés dans le résultat.
Remarque
Notez que les documents d’autorisation, créés par le répartiteur de jetons de ressource, sont stockés dans la même collection de documents que les documents créés par l’application Xamarin.Forms . Par conséquent, la requête de document contient une Where
clause qui applique un prédicat de filtrage à la requête par rapport à la collection de documents. Cette clause garantit que les documents d’autorisation ne sont pas retournés à partir de la collection de documents.
Pour plus d’informations sur la récupération de documents à partir d’une collection de documents, consultez Récupération de documents de collection de documents.
Insertion de documents
Avant d’insérer un document dans une collection de documents, la TodoItem.UserId
propriété doit être mise à jour avec la valeur utilisée comme clé de partition, comme illustré dans l’exemple de code suivant :
item.UserId = UserId;
await client.CreateDocumentAsync(collectionLink, item);
Cela garantit que le document sera inséré dans la collection partitionnée de l’utilisateur.
Pour plus d’informations sur l’insertion d’un document dans une collection de documents, consultez Insertion d’un document dans une collection de documents.
Suppression de documents
La valeur de clé de partition doit être spécifiée lors de la suppression d’un document d’une collection partitionnée, comme illustré dans l’exemple de code suivant :
await client.DeleteDocumentAsync(UriFactory.CreateDocumentUri(Constants.DatabaseName, Constants.CollectionName, id),
new RequestOptions
{
PartitionKey = new PartitionKey(UserId)
});
Cela garantit qu’Azure Cosmos DB connaît la collection partitionnée à partir de laquelle supprimer le document.
Pour plus d’informations sur la suppression d’un document d’une collection de documents, consultez Suppression d’un document d’une collection de documents.
Résumé
Cet article a expliqué comment combiner le contrôle d’accès avec des collections partitionnés afin qu’un utilisateur puisse accéder uniquement à ses propres documents de base de données de documents dans une Xamarin.Forms application. La spécification de l’identité de l’utilisateur en tant que clé de partition garantit qu’une collection partitionnée ne peut stocker que des documents pour cet utilisateur.