Проверка подлинности пользователей с помощью базы данных документов Azure Cosmos DB и Xamarin.Forms

Download Sample Скачайте пример

Базы данных документов Azure Cosmos DB поддерживают секционированные коллекции, которые могут охватывать несколько серверов и секций, поддерживая неограниченное хранилище и пропускную способность. В этой статье объясняется, как объединить управление доступом с секционированных коллекций, чтобы пользователь смог получить доступ только к собственным документам в Xamarin.Forms приложении.

Обзор

Ключ секции должен быть указан при создании секционированных коллекций, а документы с тем же ключом секции будут храниться в той же секции. Таким образом, указание удостоверения пользователя в качестве ключа секции приведет к секционированной коллекции, которая будет хранить только документы для этого пользователя. Это также гарантирует, что база данных документов Azure Cosmos DB будет масштабироваться по мере увеличения числа пользователей и элементов.

Доступ должен быть предоставлен любой коллекции, а модель управления доступом Azure Cosmos DB для NoSQL определяет два типа конструкций доступа:

  • Основные ключи обеспечивают полный административный доступ ко всем ресурсам в учетной записи Azure Cosmos DB и создаются при создании учетной записи Azure Cosmos DB.
  • Маркеры ресурсов фиксируют связь между пользователем базы данных и разрешением, которое пользователь имеет для определенного ресурса Azure Cosmos DB, например коллекции или документа.

Предоставление главного ключа открывает учетную запись Azure Cosmos DB для возможности вредоносного или небрежного использования. Однако маркеры ресурсов Azure Cosmos DB предоставляют безопасный механизм для чтения, записи и удаления определенных ресурсов в учетной записи Azure Cosmos DB в соответствии с предоставленными разрешениями.

Типичный подход к запросу, созданию и доставке маркеров ресурсов в мобильное приложение заключается в использовании брокера маркеров ресурсов. На следующей схеме показан общий обзор того, как пример приложения использует брокер маркеров ресурсов для управления доступом к данным базы данных документов:

Document Database Authentication Process

Брокер маркеров ресурсов — это служба веб-API среднего уровня, размещенная в службе приложение Azure, которая обладает главным ключом учетной записи Azure Cosmos DB. Пример приложения использует брокер маркеров ресурсов для управления доступом к данным базы данных документов следующим образом:

  1. При входе Xamarin.Forms приложение обращается к службе приложение Azure для запуска потока проверки подлинности.
  2. служба приложение Azure выполняет поток проверки подлинности OAuth с помощью Facebook. После завершения Xamarin.Forms потока проверки подлинности приложение получает маркер доступа.
  3. Приложение Xamarin.Forms использует маркер доступа для запроса маркера ресурса от брокера маркеров ресурсов.
  4. Брокер маркеров ресурсов использует маркер доступа для запроса удостоверения пользователя из Facebook. Затем удостоверение пользователя используется для запроса маркера ресурса из Azure Cosmos DB, который используется для предоставления доступа для чтения и записи к секционированной коллекции прошедших проверку подлинности пользователей.
  5. Приложение Xamarin.Forms использует маркер ресурса для прямого доступа к ресурсам Azure Cosmos DB с разрешениями, определенными маркером ресурса.

Примечание.

После истечения срока действия маркера ресурса последующие запросы базы данных документов получат 401 несанкционированное исключение. На этом этапе Xamarin.Forms приложения должны повторно установить удостоверение и запросить новый маркер ресурса.

Дополнительные сведения о секционированиях Azure Cosmos DB см. в статье "Как секционировать и масштабировать" в Azure Cosmos DB. Дополнительные сведения об управлении доступом к Azure Cosmos DB см. в статье "Защита доступа к данным Azure Cosmos DB и управление доступом" в Azure Cosmos DB для NoSQL.

Настройка

Процесс интеграции брокера маркеров ресурсов в Xamarin.Forms приложение выглядит следующим образом:

  1. Создайте учетную запись Azure Cosmos DB, которая будет использовать управление доступом. Дополнительные сведения см. в разделе "Конфигурация Azure Cosmos DB".
  2. Создайте службу приложение Azure для размещения брокера маркеров ресурсов. Дополнительные сведения см. в разделе приложение Azure Конфигурация службы.
  3. Создайте приложение Facebook для выполнения проверки подлинности. Дополнительные сведения см. в Конфигурация приложений Facebook.
  4. Настройте службу приложение Azure для простой проверки подлинности с помощью Facebook. Дополнительные сведения см. в разделе приложение Azure Конфигурация проверки подлинности службы.
  5. Xamarin.Forms Настройте пример приложения для взаимодействия со службой приложение Azure и Azure Cosmos DB. Дополнительные сведения см. в разделе Xamarin.Forms "Конфигурация приложений".

Примечание.

Если у вас еще нет подписки Azure, создайте бесплатную учетную запись Azure, прежде чем начать работу.

Конфигурация Azure Cosmos DB

Процесс создания учетной записи Azure Cosmos DB, которая будет использовать управление доступом, выглядит следующим образом:

  1. Создайте учетную запись Azure Cosmos DB. Дополнительные сведения см. в статье "Создание учетной записи Azure Cosmos DB".
  2. В учетной записи Azure Cosmos DB создайте новую коллекцию с именем UserItems, указав ключ секции /userid.

Конфигурация службы приложение Azure

Процесс размещения брокера маркеров ресурсов в службе приложение Azure выглядит следующим образом:

  1. В портал Azure создайте новое веб-приложение Служба приложений. Дополнительные сведения см. в статье "Создание веб-приложения в Среда службы приложений".

  2. В портал Azure откройте колонку "Приложение Параметры" для веб-приложения и добавьте следующие параметры:

    • accountUrl — значение должно быть URL-адресом учетной записи Azure Cosmos DB из колонки "Ключи" учетной записи Azure Cosmos DB.
    • accountKey — значение должно быть главным ключом Azure Cosmos DB (первичным или вторичным) в колонке "Ключи" учетной записи Azure Cosmos DB.
    • databaseId — значение должно быть именем базы данных Azure Cosmos DB.
    • collectionId — значение должно быть именем коллекции Azure Cosmos DB (в данном случае UserItems).
    • hostUrl— значение должно быть URL-адресом веб-приложения из колонки "Обзор" учетной записи Служба приложений.

    На следующем снимках экрана показана эта конфигурация:

    App Service Web App Settings

  3. Опубликуйте решение брокера маркеров ресурсов в веб-приложении службы приложение Azure.

Facebook Конфигурация приложений

Процесс создания приложения Facebook для выполнения проверки подлинности выглядит следующим образом:

  1. Создайте приложение Facebook. Дополнительные сведения см. в разделе "Регистрация и настройка приложения " в Центре разработчиков Facebook.
  2. Добавьте продукт входа Facebook в приложение. Дополнительные сведения см. в разделе "Добавление входа Facebook в приложение или веб-сайт " в Центре разработчиков Facebook.
  3. Настройте facebook Login следующим образом:
    • Включите имя входа OAuth клиента.
    • Включение входа в Веб-OAuth.
    • Задайте допустимый URI перенаправления OAuth в URI веб-приложения Служба приложений с /.auth/login/facebook/callback добавлением.

На следующем снимках экрана показана эта конфигурация:

Facebook Login OAuth Settings

Дополнительные сведения см. в статье "Регистрация приложения в Facebook".

Конфигурация проверки подлинности службы приложение Azure

Процесс настройки Служба приложений простой проверки подлинности выглядит следующим образом:

  1. На портале Azure перейдите к веб-приложению Служба приложений.

  2. На портале Azure откройте колонку проверки подлинности и авторизации и выполните следующую конфигурацию:

    • Служба приложений проверка подлинности должна быть включена.
    • Действие, выполняемое, если запрос не прошел проверку подлинности, следует задать для входа в Систему с помощью Facebook.

    На следующем снимках экрана показана эта конфигурация:

    App Service Web App Authentication Settings

Веб-приложение Служба приложений также должно быть настроено для взаимодействия с приложением Facebook, чтобы включить поток проверки подлинности. Это можно сделать, выбрав поставщика удостоверений Facebook и введя значения идентификатора приложения и секрета приложения из параметров приложения Facebook в Центре разработчиков Facebook. Дополнительные сведения см. в разделе "Добавление сведений о Facebook" в приложение.

Xamarin.Forms Конфигурация приложения

Процесс настройки Xamarin.Forms примера приложения выглядит следующим образом:

  1. Xamarin.Forms Откройте решение.
  2. Откройте Constants.cs и обновите значения следующих констант:
    • EndpointUri — значение должно быть URL-адресом учетной записи Azure Cosmos DB из колонки "Ключи" учетной записи Azure Cosmos DB.
    • DatabaseName — значение должно быть именем базы данных документов.
    • CollectionName — значение должно быть именем коллекции базы данных документов (в данном случае UserItems).
    • ResourceTokenBrokerUrl— значение должно быть URL-адресом веб-приложения брокера маркеров ресурсов из колонки "Обзор" учетной записи Служба приложений.

Инициирование имени входа

Пример приложения инициирует процесс входа, перенаправляя браузер на URL-адрес поставщика удостоверений, как показано в следующем примере кода:

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

Это приводит к тому, что поток проверки подлинности OAuth инициируется между службой приложение Azure и Facebook, где отображается страница входа в Facebook:

Facebook Login

Имя входа можно отменить, нажав кнопку "Отмена " в iOS или нажав кнопку "Назад " в Android, в этом случае пользователь остается не прошедшим проверку подлинности, а пользовательский интерфейс поставщика удостоверений удаляется с экрана.

Получение маркера ресурса

После успешной WebRedirectAuthenticator.Completed проверки подлинности событие запускается. В следующем примере кода демонстрируется обработка этого события:

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

Результат успешной проверки подлинности — это маркер доступа, который является доступным AuthenticatorCompletedEventArgs.Account свойством. Маркер доступа извлекается и используется в запросе GET к API брокера resourcetoken маркеров ресурсов.

resourcetoken API использует маркер доступа для запроса удостоверения пользователя из Facebook, который, в свою очередь, используется для запроса маркера ресурса из Azure Cosmos DB. Если действительный документ разрешений уже существует для пользователя в базе данных документов, он извлекается и json-документ, содержащий маркер ресурса, возвращается приложению Xamarin.Forms . Если для пользователя не существует допустимый документ разрешений, пользователь и разрешение создаются в базе данных документов, а маркер ресурса извлекается из документа разрешения и возвращается Xamarin.Forms приложению в документе JSON.

Примечание.

Пользователь базы данных документов — это ресурс, связанный с базой данных документов, и каждая база данных может содержать ноль или больше пользователей. Разрешение базы данных документов — это ресурс, связанный с пользователем базы данных документов, и каждый пользователь может содержать ноль или больше разрешений. Ресурс разрешений предоставляет доступ к маркеру безопасности, который требуется пользователю при попытке доступа к ресурсу, например к документу.

resourcetoken Если API успешно завершится, он отправит код состояния HTTP 200 (ОК) в ответе вместе с документом JSON, содержащим маркер ресурса. Следующие данные JSON показывают типичное сообщение об успешном ответе:

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

Обработчик WebRedirectAuthenticator.Completed событий считывает ответ из resourcetoken API и извлекает маркер ресурса и идентификатор пользователя. Затем маркер ресурса передается в качестве аргумента DocumentClient конструктору, который инкапсулирует конечную точку, учетные данные и политику подключения, используемую для доступа к Azure Cosmos DB, и используется для настройки и выполнения запросов к Azure Cosmos DB. Маркер ресурса отправляется с каждым запросом для прямого доступа к ресурсу и указывает, что предоставляется доступ на чтение и запись к секционированной коллекции пользователей, прошедших проверку подлинности.

Извлечение документов

Получение документов, принадлежащих только прошедшему проверку подлинности пользователя, можно добиться путем создания запроса документа, включающего идентификатор пользователя в качестве ключа секции, и демонстрируется в следующем примере кода:

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

Запрос асинхронно извлекает все документы, принадлежащие прошедшему проверку подлинности, из указанной коллекции, и помещает их в List<TodoItem> коллекцию для отображения.

Метод CreateDocumentQuery<T> задает Uri аргумент, представляющий коллекцию, которая должна запрашиваться для документов и FeedOptions объекта. Объект FeedOptions указывает, что неограниченное количество элементов может быть возвращено запросом, и идентификатор пользователя в качестве ключа секции. Это гарантирует, что в результате возвращаются только документы в секционированной коллекции пользователя.

Примечание.

Обратите внимание, что документы разрешений, созданные брокером маркеров ресурсов, хранятся в той же коллекции документов, что и документы, созданные приложением Xamarin.Forms . Поэтому запрос документа содержит Where предложение, которое применяет предикат фильтрации к запросу к коллекции документов. Это предложение гарантирует, что документы разрешений не возвращаются из коллекции документов.

Дополнительные сведения о получении документов из коллекции документов см. в разделе "Получение документов коллекции документов".

Вставка документов

Перед вставкой документа в коллекцию документов свойство должно быть обновлено со значением, TodoItem.UserId используемым в качестве ключа секции, как показано в следующем примере кода:

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

Это гарантирует, что документ будет вставлен в секционированную коллекцию пользователя.

Дополнительные сведения о вставке документа в коллекцию документов см. в разделе "Вставка документа в коллекцию документов".

Удаление документов

Значение ключа секции необходимо указать при удалении документа из секционированных коллекций, как показано в следующем примере кода:

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

Это гарантирует, что Azure Cosmos DB знает, какую секционированную коллекцию следует удалить из документа.

Дополнительные сведения об удалении документа из коллекции документов см. в разделе "Удаление документа из коллекции документов".

Итоги

В этой статье объясняется, как объединить управление доступом с секционированных коллекциями, чтобы пользователь смог получить доступ только к собственным документам базы данных документов в Xamarin.Forms приложении. Указание удостоверения пользователя в качестве ключа секции гарантирует, что секционированная коллекция может хранить только документы для этого пользователя.