Autenticación de usuarios con una base de datos de documentos de Azure Cosmos DB yXamarin.Forms
Las bases de datos de documentos de Azure Cosmos DB admiten colecciones con particiones, que pueden abarcar varios servidores y particiones, a la vez que admiten almacenamiento y rendimiento ilimitados. En este artículo se explica cómo combinar el control de acceso con colecciones con particiones para que un usuario solo pueda acceder a sus propios documentos en una Xamarin.Forms aplicación.
Información general
Se debe especificar una clave de partición al crear una colección con particiones y los documentos con la misma clave de partición se almacenarán en la misma partición. Por lo tanto, la especificación de la identidad del usuario como clave de partición dará como resultado una colección con particiones que solo almacenará documentos para ese usuario. Esto también garantiza que la base de datos de documentos de Azure Cosmos DB se escalará a medida que aumente el número de usuarios y elementos.
El acceso se debe conceder a cualquier colección y el modelo de control de acceso de SQL API define dos tipos de construcciones de acceso:
- Las claves maestras permiten el acceso administrativo total a todos los recursos de una cuenta de Cosmos DB y se crean cuando se crea Cosmos cuenta de base de datos.
- Los tokens de recursos capturan la relación entre el usuario de una base de datos y el permiso que el usuario tiene para un recurso de base de datos de Cosmos específico, como una colección o un documento.
Al exponer una clave maestra, se abre Cosmos cuenta de base de datos ante la posibilidad de un uso malintencionado o negente. Sin embargo, los tokens de recursos de Azure Cosmos DB proporcionan un mecanismo seguro para permitir a los clientes leer, escribir y eliminar recursos específicos en una cuenta de Azure Cosmos DB según los permisos concedidos.
Un enfoque típico para solicitar, generar y entregar tokens de recursos a una aplicación móvil es usar un agente de token de recursos. En el diagrama siguiente se muestra información general de alto nivel sobre cómo la aplicación de ejemplo usa un agente de token de recursos para administrar el acceso a los datos de la base de datos de documentos:

El agente de token de recursos es un servicio de API web de nivel intermedio, hospedado en Azure App Service, que posee la clave maestra de la cuenta de Cosmos DB. La aplicación de ejemplo usa el agente de token de recursos para administrar el acceso a los datos de la base de datos del documento de la manera siguiente:
- Al iniciar sesión, la Xamarin.Forms aplicación se Azure App Service para iniciar un flujo de autenticación.
- Azure App Service realiza un flujo de autenticación de OAuth con Facebook. Una vez completado el flujo de autenticación, Xamarin.Forms la aplicación recibe un token de acceso.
- La Xamarin.Forms aplicación usa el token de acceso para solicitar un token de recurso al agente de token de recursos.
- El agente de token de recursos usa el token de acceso para solicitar la identidad del usuario de Facebook. A continuación, la identidad del usuario se usa para solicitar un token de recurso de Cosmos DB, que se usa para conceder acceso de lectura y escritura a la colección con particiones del usuario autenticado.
- La aplicación usa el token de recurso para acceder directamente a Cosmos db con los Xamarin.Forms permisos definidos por el token de recurso.
Nota:
Cuando expire el token de recurso, las solicitudes de base de datos de documentos posteriores recibirán una excepción 401 no autorizada. En este momento, Xamarin.Forms las aplicaciones deben volver a establecer la identidad y solicitar un nuevo token de recurso.
Para más información sobre la creación Cosmos de base de datos, consulte Creación de particiones y escalado en Azure Cosmos DB. Para obtener más información sobre Cosmos db access control, consulte Securing access to Cosmos DB data and Access control in the SQL API (Protección del acceso a los datos de base de datos de Cosmos y Control de acceso en SQL API).
Configurar
El proceso para integrar el agente de token de recursos en una Xamarin.Forms aplicación es el siguiente:
- Cree una cuenta Cosmos DB que usará el control de acceso. Para más información, consulte Configuración de Azure Cosmos DB.
- Cree un Azure App Service para hospedar el agente de token de recursos. Para obtener más información, vea Azure App Service configuration.
- Cree una aplicación de Facebook para realizar la autenticación. Para obtener más información, vea Facebook App Configuration.
- Configure el Azure App Service para realizar una autenticación sencilla con Facebook. Para obtener más información, vea configuración Azure App Service autenticación de servidor.
- Configure la Xamarin.Forms aplicación de ejemplo para comunicarse con Azure App Service y Cosmos db. Para obtener más información, vea Xamarin.Forms Application Configuration.
Nota:
Si no tiene una suscripción a Azure, cree una cuenta gratuita antes de empezar.
Configuración de Azure Cosmos DB
El proceso para crear una cuenta Cosmos DB que usará el control de acceso es el siguiente:
- Cree una cuenta Cosmos DB. Para más información, consulte Creación de una cuenta de Azure Cosmos DB.
- En la Cosmos db, cree una colección denominada
UserItems, especificando una clave de partición de/userid.
Azure App Service configuración
El proceso para hospedar el agente de token de recursos en Azure App Service es el siguiente:
En la Azure Portal, cree una nueva aplicación App Service web. Para obtener más información, consulte Creación de una aplicación web en un App Service Environment.
En la Azure Portal, abra la hoja App Configuración de la aplicación web y agregue la siguiente configuración:
accountUrl: el valor debe ser la dirección URL Cosmos de la cuenta de base de datos de la hoja Claves de la Cosmos de base de datos.accountKey: el valor debe ser la clave maestra Cosmos base de datos principal (principal o secundaria) de la hoja Claves de la Cosmos de base de datos.databaseId: el valor debe ser el nombre de la base de datos Cosmos base de datos.collectionId: el valor debe ser el nombre de la colección Cosmos DB (en este caso,UserItems).hostUrl: el valor debe ser la dirección URL de la aplicación web en la hoja Información general de App Service cuenta.
En la captura de pantalla siguiente se muestra esta configuración:
Publique la solución de agente de token de recursos en la Azure App Service web.
Facebook App Configuration
El proceso para crear una aplicación de Facebook para realizar la autenticación es el siguiente:
- Cree una aplicación de Facebook. Para más información, consulte Registro y configuración de una aplicación en el Centro para desarrolladores de Facebook.
- Agregue el producto Inicio de sesión de Facebook a la aplicación. Para más información, consulte Add Facebook Login to Your App or Website (Agregar inicio de sesión de Facebook a su aplicación o sitio web) en el Centro para desarrolladores de Facebook.
- Configure el inicio de sesión de Facebook como se muestra a continuación:
- Habilite el inicio de sesión de OAuth del cliente.
- Habilite el inicio de sesión de Web OAuth.
- Establezca el URI de redireccionamiento de OAuth válido en el URI de la App Service web,
/.auth/login/facebook/callbackcon anexado.
En la captura de pantalla siguiente se muestra esta configuración:

Para más información, consulte Registro de la aplicación con Facebook.
Azure App Service de autenticación
El proceso para configurar App Service autenticación sencilla es el siguiente:
En Azure Portal, vaya a la App Service web.
En Azure Portal, abra la hoja Autenticación/autorización y realice la configuración siguiente:
- App Service autenticación debe estar activada.
- La acción que se debe realizar cuando una solicitud no está autenticada debe establecerse en Iniciar sesión con Facebook.
En la captura de pantalla siguiente se muestra esta configuración:
La App Service web debe configurarse también para comunicarse con la aplicación de Facebook para habilitar el flujo de autenticación. Para ello, seleccione el proveedor de identidades de Facebook y escriba los valores de Id. de aplicación y Secreto de aplicación en la configuración de la aplicación de Facebook en el Centro para desarrolladores de Facebook. Para obtener más información, vea Agregar información de Facebook a la aplicación.
Xamarin.Forms Configuración de la aplicación
El proceso para configurar la Xamarin.Forms aplicación de ejemplo es el siguiente:
- Abra la Xamarin.Forms solución.
- Abra
Constants.csy actualice los valores de las constantes siguientes:EndpointUri: el valor debe ser la dirección URL Cosmos de la cuenta de base de datos de la hoja Claves de la Cosmos de base de datos.DatabaseName: el valor debe ser el nombre de la base de datos de documentos.CollectionName: el valor debe ser el nombre de la colección de bases de datos de documentos (en este caso,UserItems).ResourceTokenBrokerUrl: el valor debe ser la dirección URL de la aplicación web del agente de token de recursos de la hoja Información general de App Service cuenta.
Inicio de sesión
La aplicación de ejemplo inicia el proceso de inicio de sesión mediante la redirección de un explorador a una dirección URL del proveedor de identidades, como se muestra en el código de ejemplo siguiente:
var auth = new Xamarin.Auth.WebRedirectAuthenticator(
new Uri(Constants.ResourceTokenBrokerUrl + "/.auth/login/facebook"),
new Uri(Constants.ResourceTokenBrokerUrl + "/.auth/login/done"));
Esto hace que se inicie un flujo de autenticación de OAuth entre Azure App Service y Facebook, que muestra la página de inicio de sesión de Facebook:

El inicio de sesión se puede cancelar presionando el botón Cancelar en iOS o presionando el botón Atrás en Android, en cuyo caso el usuario permanece sin autenticar y la interfaz de usuario del proveedor de identidades se quita de la pantalla.
Obtención de un token de recurso
Después de la autenticación correcta, WebRedirectAuthenticator.Completed se produce el evento . En el ejemplo de código siguiente se muestra cómo controlar este 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);
...
}
...
}
}
};
El resultado de una autenticación correcta es un token de acceso, que es una propiedad AuthenticatorCompletedEventArgs.Account disponible. El token de acceso se extrae y se usa en una solicitud GET a la API del agente de token de resourcetoken recursos.
La API usa el token de acceso para solicitar la identidad del usuario de Facebook, que a su vez se usa para solicitar un token de recurso resourcetoken a Cosmos DB. Si ya existe un documento de permiso válido para el usuario en la base de datos de documentos, se recupera y se devuelve a la aplicación un documento JSON que contiene el token de Xamarin.Forms recurso. Si no existe un documento de permiso válido para el usuario, se crea un usuario y un permiso en la base de datos de documentos, y el token de recurso se extrae del documento de permiso y se devuelve a la aplicación en un Xamarin.Forms documento JSON.
Nota:
Un usuario de base de datos de documentos es un recurso asociado a una base de datos de documentos y cada base de datos puede contener cero o más usuarios. Un permiso de base de datos de documentos es un recurso asociado a un usuario de base de datos de documentos y cada usuario puede contener cero o más permisos. Un recurso de permiso proporciona acceso a un token de seguridad que el usuario necesita al intentar acceder a un recurso como un documento.
Si la API se completa correctamente, enviará el código de estado HTTP 200 (Correcto) en la respuesta, junto con un documento JSON que resourcetoken contiene el token de recurso. Los siguientes datos JSON muestran un mensaje de respuesta correcto típico:
{
"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"
}
El WebRedirectAuthenticator.Completed controlador de eventos lee la respuesta de la API y extrae el token de recurso y el identificador resourcetoken de usuario. A continuación, el token de recurso se pasa como argumento al constructor, que encapsula el punto de conexión, las credenciales y la directiva de conexión que se usan para acceder Cosmos la base de datos, y se usa para configurar y ejecutar solicitudes en Cosmos DocumentClient DB. El token de recurso se envía con cada solicitud para acceder directamente a un recurso e indica que se concede acceso de lectura y escritura a la colección con particiones de los usuarios autenticados.
Recuperar documentos
La recuperación de documentos que solo pertenecen al usuario autenticado se puede lograr mediante la creación de una consulta de documento que incluya el identificador del usuario como clave de partición y se muestra en el ejemplo de código siguiente:
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 consulta recupera de forma asincrónica todos los documentos que pertenecen al usuario autenticado, de la colección especificada, y los coloca en una colección List<TodoItem> para su presentación.
El método especifica un argumento que representa la colección que se debe consultar para los documentos CreateDocumentQuery<T> y un objeto UriFeedOptions . El objeto especifica que la consulta puede devolver un número ilimitado de elementos y el identificador del usuario FeedOptions como clave de partición. Esto garantiza que solo se devuelvan los documentos de la colección con particiones del usuario en el resultado.
Nota:
Tenga en cuenta que los documentos de permiso, creados por el agente de token de recursos, se almacenan en la misma colección de documentos que los documentos creados por la Xamarin.Forms aplicación. Por lo tanto, la consulta de documento contiene una Where cláusula que aplica un predicado de filtrado a la consulta en la colección de documentos. Esta cláusula garantiza que los documentos de permiso no se devuelven de la colección de documentos.
Para obtener más información sobre cómo recuperar documentos de una colección de documentos, vea Recuperar documentos de colección de documentos.
Insertar documentos
Antes de insertar un documento en una colección de documentos, la propiedad debe actualizarse con el valor que se usa como clave de partición, como se muestra en el TodoItem.UserId ejemplo de código siguiente:
item.UserId = UserId;
await client.CreateDocumentAsync(collectionLink, item);
Esto garantiza que el documento se insertará en la colección con particiones del usuario.
Para obtener más información sobre cómo insertar un documento en una colección de documentos, vea Insertar un documento en una colección de documentos.
Eliminación de documentos
El valor de clave de partición debe especificarse al eliminar un documento de una colección con particiones, como se muestra en el ejemplo de código siguiente:
await client.DeleteDocumentAsync(UriFactory.CreateDocumentUri(Constants.DatabaseName, Constants.CollectionName, id),
new RequestOptions
{
PartitionKey = new PartitionKey(UserId)
});
Esto garantiza que Cosmos db sabe de qué colección con particiones se va a eliminar el documento.
Para obtener más información sobre cómo eliminar un documento de una colección de documentos, vea Eliminar un documento de una colección de documentos.
Resumen
En este artículo se explica cómo combinar el control de acceso con colecciones con particiones para que un usuario solo pueda acceder a sus propios documentos de base de datos de documentos en una Xamarin.Forms aplicación. La especificación de la identidad del usuario como clave de partición garantiza que una colección con particiones solo pueda almacenar documentos para ese usuario.
Descarga del ejemplo
