Partilhar via


Autenticar usuários com um Banco de Dados de Documentos do Azure Cosmos DB e Xamarin.Forms

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 oferecem 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 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 será 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 para NoSQL define dois tipos de construções de acesso:

  • As chaves mestras permitem acesso administrativo total 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 mestra 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, gravem 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 de documentos:

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

O agente de token de recurso é um serviço de API Web de camada intermediária, hospedado no Serviço de Aplicativo do Azure, que possui a chave mestra 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 de documentos da seguinte maneira:

  1. No logon, o aplicativo entra em contato com o Xamarin.Forms Serviço de Aplicativo do Azure para iniciar um fluxo de autenticação.
  2. O 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 corretor de token de recurso usa o token de acesso para solicitar a identidade do usuário do Facebook. 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 subsequentes do banco de dados de documentos receberão uma exceção não autorizada 401. 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 o Controle de acesso no Azure Cosmos DB para NoSQL.

Instalação

O processo para integrar o 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 Configuração do aplicativo do Facebook.
  4. Configure o Serviço de Aplicativo do Azure para executar autenticação fácil com o Facebook. Para obter mais informações, consulte Configuração de autenticação do Serviço de Aplicativo do Azure.
  5. Configure o aplicativo de exemplo para se comunicar com o Serviço de Aplicativo do Azure e o Xamarin.Forms 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 do Serviço de Aplicativo. Para obter mais informações, consulte Criar um aplicativo Web em um ambiente do Serviço de Aplicativo.

  2. No 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 da folha Chaves da conta do Azure Cosmos DB.
    • accountKey – o valor deve ser a chave mestra do Azure Cosmos DB (primária ou secundária) da 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 (neste caso, UserItems).
    • hostUrl – o valor deve ser a URL do aplicativo Web da folha Visão geral da conta do Serviço de Aplicativo.

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

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

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

Configuração do aplicativo do Facebook

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

  1. Crie um aplicativo do Facebook. Para obter mais informações, consulte Registrar e configurar um aplicativo no Facebook Developer Center.
  2. Adicione o produto Login do Facebook ao aplicativo. Para obter mais informações, consulte Adicionar login do Facebook ao seu aplicativo ou site no Facebook Developer Center.
  3. Configure o Login do Facebook da seguinte maneira:
    • Habilite o login do cliente OAuth.
    • Habilite o Login OAuth da Web.
    • Defina o URI de redirecionamento OAuth válido para o URI do aplicativo Web do Serviço de Aplicativo, com /.auth/login/facebook/callback acréscimo.

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

Configurações OAuth de login do Facebook

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

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

O processo para configurar a autenticação fácil do Serviço de Aplicativo é o seguinte:

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

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

    • A Autenticação do Serviço de Aplicativo deve estar ativada.
    • A ação a ser executada quando uma solicitação não for autenticada deve ser definida como Fazer login com o Facebook.

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

    Configurações de autenticação de aplicativo Web do Serviço de Aplicativo

O aplicativo Web do 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 do Facebook no Facebook Developer Center. 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 Xamarin.Forms aplicativo de exemplo é o 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 da folha Chaves da conta do Azure Cosmos DB.
    • DatabaseName – o valor deve ser o nome do banco de dados de documentos.
    • CollectionName – o valor deve ser o nome da coleção de banco de dados de documentos (neste caso, UserItems).
    • ResourceTokenBrokerUrl – o valor deve ser a URL do aplicativo Web do agente de token de recurso da folha Visão geral da conta do Serviço de Aplicativo.

Iniciando o login

O aplicativo de exemplo inicia o processo de logon redirecionando um navegador para uma URL de 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 o Serviço de Aplicativo do Azure e o Facebook, que exibe a página de logon do Facebook:

Facebook Login

O login pode ser cancelado pressionando o botão Cancelar no iOS ou pressionando o botão Voltar no Android, caso em que 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 WebRedirectAuthenticator.Completed evento é acionado. O exemplo de código a seguir demonstra como manipular 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 é propriedade 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 de documentos, ele será recuperado e um documento JSON contendo 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 de documentos, 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 documentos é um recurso associado a um banco de dados de documentos, e cada banco de dados pode conter zero ou mais usuários. Uma permissão de banco de dados de documentos é um recurso associado a um usuário de banco de dados de documentos, 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á o código de status HTTP 200 (OK) na resposta, juntamente com um documento JSON contendo o token de recurso. Os dados JSON a seguir mostram uma mensagem de resposta bem-sucedida típica:

{
  "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 resourcetoken resposta da API e extrai o token de recurso e a ID do usuário. 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 usados 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 os documentos na coleção particionada do usuário sejam retornados no resultado.

Observação

Observe que os documentos de permissão, que sã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 em relação à 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 que está 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 será 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 Inserindo 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 só possa acessar 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.