Autenticar usuários com um banco de dados de documentos do Azure Cosmos DB e Xamarin.Forms

Baixar exemplo Baixar o exemplo

Os bancos de dados de documentos do Azure Cosmos DB dão suporte a coleções particionadas, que podem abranger vários servidores e partições, ao mesmo tempo em que dão suporte a armazenamento e taxa de transferência ilimitados. Este artigo explica como combinar o controle de acesso com coleções particionadas, para que um usuário só possa acessar seus próprios documentos em um Xamarin.Forms aplicativo.

Visão geral

Uma chave de partição deve ser especificada ao criar uma coleção particionada e os documentos com a mesma chave de partição serão armazenados na mesma partição. Portanto, especificar a identidade do usuário como uma chave de partição resultará em uma coleção particionada que armazenará apenas documentos para esse usuário. Isso também garante que o banco de dados de documentos do Azure Cosmos DB seja dimensionado à medida que o número de usuários e itens aumentar.

O acesso deve ser concedido a qualquer coleção e o modelo de controle de acesso do Azure Cosmos DB for NoSQL define dois tipos de constructos de acesso:

  • As chaves mestras permitem o acesso administrativo completo a todos os recursos em uma conta do Azure Cosmos DB e são criadas quando uma conta do Azure Cosmos DB é criada.
  • Os tokens de recurso capturam a relação entre o usuário de um banco de dados e a permissão que o usuário tem para um recurso específico do Azure Cosmos DB, como uma coleção ou um documento.

Expor uma chave de master abre uma conta do Azure Cosmos DB para a possibilidade de uso mal-intencionado ou negligente. No entanto, os tokens de recurso do Azure Cosmos DB fornecem um mecanismo seguro para permitir que os clientes leiam, escrevam e excluam recursos específicos em uma conta do Azure Cosmos DB de acordo com as permissões concedidas.

Uma abordagem típica para solicitar, gerar e entregar tokens de recurso para um aplicativo móvel é usar um agente de token de recurso. O diagrama a seguir mostra uma visão geral de alto nível de como o aplicativo de exemplo usa um agente de token de recurso para gerenciar o acesso aos dados do banco de dados do documento:

Processo de autenticação de banco de dados do documento

O agente de token de recurso é um serviço de API Web de camada intermediária, hospedado em Serviço de Aplicativo do Azure, que possui a chave de master da conta do Azure Cosmos DB. O aplicativo de exemplo usa o agente de token de recurso para gerenciar o acesso aos dados do banco de dados do documento da seguinte maneira:

  1. No logon, o Xamarin.Forms aplicativo entra em contato com Serviço de Aplicativo do Azure para iniciar um fluxo de autenticação.
  2. Serviço de Aplicativo do Azure executa um fluxo de autenticação OAuth com o Facebook. Após a conclusão do fluxo de autenticação, o Xamarin.Forms aplicativo recebe um token de acesso.
  3. O Xamarin.Forms aplicativo usa o token de acesso para solicitar um token de recurso do agente de token de recurso.
  4. O agente de token de recurso usa o token de acesso para solicitar a identidade do usuário do Facebook. Em seguida, a identidade do usuário é usada para solicitar um token de recurso do Azure Cosmos DB, que é usado para conceder acesso de leitura/gravação à coleção particionada do usuário autenticado.
  5. O Xamarin.Forms aplicativo usa o token de recurso para acessar diretamente os recursos do Azure Cosmos DB com as permissões definidas pelo token de recurso.

Observação

Quando o token de recurso expirar, as solicitações de banco de dados de documentos subsequentes receberão uma exceção 401 não autorizada. Neste ponto, Xamarin.Forms os aplicativos devem restabelecer a identidade e solicitar um novo token de recurso.

Para obter mais informações sobre o particionamento do Azure Cosmos DB, consulte Como particionar e dimensionar no Azure Cosmos DB. Para obter mais informações sobre o controle de acesso do Azure Cosmos DB, consulte Protegendo o acesso aos dados do Azure Cosmos DB e Controle de acesso no Azure Cosmos DB for NoSQL.

Instalação

O processo de integração do agente de token de recurso em um Xamarin.Forms aplicativo é o seguinte:

  1. Crie uma conta do Azure Cosmos DB que usará o controle de acesso. Para obter mais informações, consulte Configuração do Azure Cosmos DB.
  2. Crie um Serviço de Aplicativo do Azure para hospedar o agente de token de recurso. Para obter mais informações, consulte Configuração do Serviço de Aplicativo do Azure.
  3. Crie um aplicativo do Facebook para executar a autenticação. Para obter mais informações, consulte Facebook Configuração de Aplicativos.
  4. Configure o Serviço de Aplicativo do Azure para executar uma autenticação fácil com o Facebook. Para obter mais informações, consulte Serviço de Aplicativo do Azure Configuração de Autenticação.
  5. Configure o Xamarin.Forms aplicativo de exemplo para se comunicar com o Serviço de Aplicativo do Azure e o Azure Cosmos DB. Para obter mais informações, consulte Xamarin.Forms Configuração do Aplicativo.

Observação

Se você não tiver uma assinatura do Azure, crie uma conta gratuita antes de começar.

Configuração do Azure Cosmos DB

O processo para criar uma conta do Azure Cosmos DB que usará o controle de acesso é o seguinte:

  1. Criar uma conta do Azure Cosmos DB. Para obter mais informações, consulte Criar uma conta do Azure Cosmos DB.
  2. Na conta do Azure Cosmos DB, crie uma nova coleção chamada UserItems, especificando uma chave de partição de /userid.

Configuração do Serviço de Aplicativo do Azure

O processo para hospedar o agente de token de recurso no Serviço de Aplicativo do Azure é o seguinte:

  1. No portal do Azure, crie um novo aplicativo Web Serviço de Aplicativo. Para obter mais informações, consulte Criar um aplicativo Web em um Ambiente do Serviço de Aplicativo.

  2. Na portal do Azure, abra a folha Configurações do Aplicativo para o aplicativo Web e adicione as seguintes configurações:

    • accountUrl – o valor deve ser a URL da conta do Azure Cosmos DB na folha Chaves da conta do Azure Cosmos DB.
    • accountKey– o valor deve ser a chave de master do Azure Cosmos DB (primária ou secundária) na folha Chaves da conta do Azure Cosmos DB.
    • databaseId – o valor deve ser o nome do banco de dados do Azure Cosmos DB.
    • collectionId – o valor deve ser o nome da coleção do Azure Cosmos DB (nesse caso, UserItems).
    • hostUrl– o valor deve ser a URL do aplicativo Web na folha Visão geral da conta Serviço de Aplicativo.

    A captura de tela a seguir demonstra essa configuração:

    Serviço de Aplicativo Configurações do Aplicativo Web

  3. Publique a solução do agente de token de recurso no aplicativo Web Serviço de Aplicativo do Azure.

Configuração de Aplicativos do Facebook

O processo para criar um aplicativo do Facebook para executar a autenticação é o seguinte:

  1. Criar um aplicativo do Facebook. Para obter mais informações, consulte Registrar e configurar um aplicativo no Centro de Desenvolvedores do Facebook.
  2. Adicione o produto Logon do Facebook ao aplicativo. Para obter mais informações, consulte Adicionar logon do Facebook ao seu aplicativo ou site na Central de Desenvolvedores do Facebook.
  3. Configure o Logon do Facebook da seguinte maneira:
    • Habilitar logon OAuth do cliente.
    • Habilite o logon do Web OAuth.
    • Defina o URI de redirecionamento OAuth válido para o URI do aplicativo Web Serviço de Aplicativo, com /.auth/login/facebook/callback acrescentado.

A captura de tela a seguir demonstra essa configuração:

Configurações do OAuth de Logon do Facebook

Para obter mais informações, consulte Registrar seu aplicativo com o Facebook.

Configuração de autenticação do Serviço de Aplicativo do Azure

O processo de configuração Serviço de Aplicativo autenticação fácil é o seguinte:

  1. No Portal do Azure, navegue até o aplicativo Web Serviço de Aplicativo.

  2. No Portal do Azure, abra a folha Autenticação/Autorização e execute a seguinte configuração:

    • Serviço de Aplicativo Autenticação deve ser ativada.
    • A ação a ser tomada quando uma solicitação não é autenticada deve ser definida como Entrar com o Facebook.

    A captura de tela a seguir demonstra essa configuração:

    Web Serviço de Aplicativo Configurações de Autenticação de Aplicativo Web

O aplicativo Web Serviço de Aplicativo também deve ser configurado para se comunicar com o aplicativo do Facebook para habilitar o fluxo de autenticação. Isso pode ser feito selecionando o provedor de identidade do Facebook e inserindo os valores ID do Aplicativo e Segredo do Aplicativo nas configurações do aplicativo Facebook no Centro de Desenvolvedores do Facebook. Para obter mais informações, consulte Adicionar informações do Facebook ao seu aplicativo.

Xamarin.Forms Configuração do aplicativo

O processo para configurar o aplicativo de exemplo é o Xamarin.Forms seguinte:

  1. Abra a Xamarin.Forms solução.
  2. Abra Constants.cs e atualize os valores das seguintes constantes:
    • EndpointUri – o valor deve ser a URL da conta do Azure Cosmos DB na folha Chaves da conta do Azure Cosmos DB.
    • DatabaseName – o valor deve ser o nome do banco de dados do documento.
    • CollectionName – o valor deve ser o nome da coleção de banco de dados do documento (nesse caso, UserItems).
    • ResourceTokenBrokerUrl– o valor deve ser a URL do aplicativo Web do agente de token de recurso na folha Visão geral da conta Serviço de Aplicativo.

Iniciando logon

O aplicativo de exemplo inicia o processo de logon redirecionando um navegador para uma URL do provedor de identidade, conforme demonstrado no código de exemplo a seguir:

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

Isso faz com que um fluxo de autenticação OAuth seja iniciado entre Serviço de Aplicativo do Azure e o Facebook, que exibe a página de logon do Facebook:

Logon do Facebook

O logon pode ser cancelado pressionando o botão Cancelar no iOS ou pressionando o botão Voltar no Android. Nesse caso, o usuário permanece não autenticado e a interface do usuário do provedor de identidade é removida da tela.

Obtendo um token de recurso

Após a autenticação bem-sucedida, o evento é acionado WebRedirectAuthenticator.Completed . O exemplo de código a seguir demonstra como lidar com esse 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);
        ...
      }
      ...
    }
  }
};

O resultado de uma autenticação bem-sucedida é um token de acesso, que está disponível AuthenticatorCompletedEventArgs.Account . O token de acesso é extraído e usado em uma solicitação GET para a API do agente de token de resourcetoken recurso.

A resourcetoken API usa o token de acesso para solicitar a identidade do usuário do Facebook, que, por sua vez, é usado para solicitar um token de recurso do Azure Cosmos DB. Se já existir um documento de permissão válido para o usuário no banco de dados do documento, ele será recuperado e um documento JSON que contém o token de recurso será retornado ao Xamarin.Forms aplicativo. Se um documento de permissão válido não existir para o usuário, um usuário e uma permissão serão criados no banco de dados do documento e o token de recurso será extraído do documento de permissão e retornado ao Xamarin.Forms aplicativo em um documento JSON.

Observação

Um usuário de banco de dados de documento é um recurso associado a um banco de dados de documento e cada banco de dados pode conter zero ou mais usuários. Uma permissão de banco de dados de documento é um recurso associado a um usuário de banco de dados de documento e cada usuário pode conter zero ou mais permissões. Um recurso de permissão fornece acesso a um token de segurança que o usuário requer ao tentar acessar um recurso, como um documento.

Se a resourcetoken API for concluída com êxito, ela enviará HTTP status código 200 (OK) na resposta, juntamente com um documento JSON que contém o token de recurso. Os seguintes dados JSON mostram uma mensagem de resposta típica bem-sucedida:

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

O WebRedirectAuthenticator.Completed manipulador de eventos lê a resposta da resourcetoken API e extrai o token de recurso e a ID de usuário. Em seguida, o token de recurso é passado como um argumento para o DocumentClient construtor, que encapsula o ponto de extremidade, as credenciais e a política de conexão usadas para acessar o Azure Cosmos DB e é usado para configurar e executar solicitações no Azure Cosmos DB. O token de recurso é enviado com cada solicitação para acessar diretamente um recurso e indica que o acesso de leitura/gravação à coleção particionada dos usuários autenticados é concedido.

Recuperando documentos

A recuperação de documentos que pertencem apenas ao usuário autenticado pode ser obtida criando uma consulta de documento que inclui a ID do usuário como uma chave de partição e é demonstrada no exemplo de código a seguir:

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

A consulta recupera de forma assíncrona todos os documentos pertencentes ao usuário autenticado, da coleção especificada, e os coloca em uma List<TodoItem> coleção para exibição.

O CreateDocumentQuery<T> método especifica um Uri argumento que representa a coleção que deve ser consultada para documentos e um FeedOptions objeto . O FeedOptions objeto especifica que um número ilimitado de itens pode ser retornado pela consulta e a ID do usuário como uma chave de partição. Isso garante que apenas documentos na coleção particionada do usuário sejam retornados no resultado.

Observação

Observe que os documentos de permissão, criados pelo agente de token de recurso, são armazenados na mesma coleção de documentos que os documentos criados pelo Xamarin.Forms aplicativo. Portanto, a consulta de documento contém uma Where cláusula que aplica um predicado de filtragem à consulta na coleção de documentos. Essa cláusula garante que os documentos de permissão não sejam retornados da coleção de documentos.

Para obter mais informações sobre como recuperar documentos de uma coleção de documentos, consulte Recuperando documentos de coleção de documentos.

Inserindo documentos

Antes de inserir um documento em uma coleção de documentos, a TodoItem.UserId propriedade deve ser atualizada com o valor sendo usado como a chave de partição, conforme demonstrado no exemplo de código a seguir:

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

Isso garante que o documento seja inserido na coleção particionada do usuário.

Para obter mais informações sobre como inserir um documento em uma coleção de documentos, consulte Inserir um documento em uma coleção de documentos.

Excluindo documentos

O valor da chave de partição deve ser especificado ao excluir um documento de uma coleção particionada, conforme demonstrado no exemplo de código a seguir:

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

Isso garante que o Azure Cosmos DB saiba de qual coleção particionada excluir o documento.

Para obter mais informações sobre como excluir um documento de uma coleção de documentos, consulte Excluindo um documento de uma coleção de documentos.

Resumo

Este artigo explicou como combinar o controle de acesso com coleções particionadas, para que um usuário possa acessar apenas seus próprios documentos de banco de dados de documentos em um Xamarin.Forms aplicativo. Especificar a identidade do usuário como uma chave de partição garante que uma coleção particionada só possa armazenar documentos para esse usuário.