Настройка политик базы данных для фильтрации на уровне строк

Построитель данных поддерживает политики баз данных , которые фильтруют результаты запросов на основе заданных выражений. База данных оценивает эти политики как предикаты запросов (WHERE предложения), поэтому пользователи видят только те данные, к которым они могут получить доступ.

Схема последовательности, показывающая применение политик.

Когда следует использовать политики базы данных

Политики базы данных идеально подойдут в случаях, когда вам нужно:

  • Ограничение записей на основе значения поля (например, status eq 'published')
  • Фильтрация данных на основе утверждений пользователя, прошедших проверку подлинности (например, @claims.userId)
  • Реализация управления доступом на уровне строк без изменения хранимых процедур или представлений
  • Применение различных правил фильтрации для каждой роли

Замечание

Azure Cosmos DB для NoSQL в настоящее время не поддерживает политики базы данных.

Поддерживаемые действия

Политики базы данных применяются к этим действиям:

Действие Поддерживается Принцип работы
read ✔️ Да Добавляет предикат WHERE в запросы SELECT
update ✔️ Да Добавляет предикат WHERE в инструкции UPDATE
delete ✔️ Да Добавляет предикат WHERE в инструкции DELETE
create ❌ Нет Инструкции INSERT не поддерживают предикаты WHERE
execute ❌ Нет Хранимые процедуры не поддерживают предикаты запросов

Необходимые условия

  • CLI для построителя API данных (руководство по установке)
  • Существующий файл конфигурации с хотя бы одной сущностью
  • Поставщик проверки подлинности настроен (политики требуют прошедших проверку подлинности запросов)

Краткий справочник

Концепция Синтаксис Пример
Справочник полей @item.<field> @item.status
Ссылка на требование @claims.<type> @claims.userId
Равенство eq @item.ownerId eq @claims.userId
Неравенство ne @item.status ne 'draft'
Comparison gt ge lt le @item.price lt 100
Логическое AND and @item.active eq true and @item.published eq true
Логическое ИЛИ or @item.role eq 'admin' or @item.role eq 'editor'

Шаг 1. Определение выражения политики

Политики баз данных используют предикаты в стиле OData. Выражение должно иметь значение true для строки, включаемой в результаты.

Ссылки на поля с @item

Используется @item.<field> для ссылки на поля сущности. Если столбец базы данных сопоставлен с другим именем поля API, используйте сопоставленное имя.

@item.status eq 'published'

Ссылки на заявления с @claims

Используйте @claims.<claimType> для внедрения значений из токена аутентифицированного пользователя. Во время выполнения Data API builder вставляет значение утверждения в выражение.

@item.ownerId eq @claims.userId

Это важно

Если упоминаемое утверждение отсутствует в маркере, запрос отклоняется с ответом 403 - Доступ запрещён.

Составные выражения

Объедините условия, используя and или or:

@item.ownerId eq @claims.userId and @item.status ne 'deleted'

Шаг 2. Добавление политики в конфигурацию сущности

Политики задаются для каждого действия в рамках разрешений роли:

Формат файла конфигурации

{
  "entities": {
    "<entity-name>": {
      "permissions": [
        {
          "role": "<role-name>",
          "actions": [
            {
              "action": "read",
              "policy": {
                "database": "<predicate-expression>"
              }
            }
          ]
        }
      ]
    }
  }
}

Пример. Пользователь может читать только собственные записи

{
  "entities": {
    "Order": {
      "source": "dbo.Orders",
      "permissions": [
        {
          "role": "customer",
          "actions": [
            {
              "action": "read",
              "policy": {
                "database": "@item.customerId eq @claims.userId"
              }
            }
          ]
        }
      ]
    }
  }
}

Пример, несколько действий с одной политикой

Примените ту же политику для чтения, обновления и удаления:

{
  "entities": {
    "Document": {
      "source": "dbo.Documents",
      "permissions": [
        {
          "role": "author",
          "actions": [
            {
              "action": "read",
              "policy": {
                "database": "@item.authorId eq @claims.sub"
              }
            },
            {
              "action": "update",
              "policy": {
                "database": "@item.authorId eq @claims.sub"
              }
            },
            {
              "action": "delete",
              "policy": {
                "database": "@item.authorId eq @claims.sub"
              }
            }
          ]
        }
      ]
    }
  }
}

Пример: фильтр статических значений

Фильтрация по фиксированному значению, а не утверждению:

{
  "entities": {
    "Article": {
      "source": "dbo.Articles",
      "permissions": [
        {
          "role": "Anonymous",
          "actions": [
            {
              "action": "read",
              "policy": {
                "database": "@item.status eq 'published'"
              }
            }
          ]
        }
      ]
    }
  }
}

Шаг 3. Настройка с помощью интерфейса командной строки

dab update Используйте команду для добавления политик с помощью интерфейса командной строки:

dab update Order \
  --permissions "customer:read" \
  --policy-database "@item.customerId eq @claims.userId"

Подсказка

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

Как обрабатывается политика

Когда поступает запрос, конструктор API данных:

  1. Определяет эффективную роль из заголовка или системной X-MS-API-ROLE роли
  2. Производится поиск политики для комбинации сущности, роли и действия.
  3. Заменяет утверждения , заменив @claims.<type> маркеры фактическими значениями из маркера.
  4. Анализирует выражение как OData $filter
  5. Создает предикаты запросов , которые добавляются в запрос базы данных

Например, если политика — @item.ownerId eq @claims.userId, а маркер содержит userId: "user123", то созданный SQL включает:

WHERE [ownerId] = 'user123'

Замена требований

Построитель API данных извлекает утверждения из JSON веб-токена (JWT) аутентифицированного пользователя или идентификационного субъекта. К общим утверждениям относятся:

Утверждение Описание Пример значения
sub Идентификатор субъекта (идентификатор пользователя) ffffffff-eeee-dddd-cccc-bbbbbbbbbbb0
userId Пользовательский идентификатор user123
email Адрес электронной почты пользователя user@example.com
name Отображаемое имя пользователя Jane Doe
roles Членство в роли (массив) ["reader", "editor"]

Предупреждение

Если утверждение, на которое ссылается политика, не существует в маркере, конструктор API данных отклоняет запрос с ответом 403 Доступ запрещён. Убедитесь, что поставщик удостоверений включает все необходимые утверждения.

Комбинировать с ограничениями полей

Политики работают вместе с контролем доступа на уровне поля. Можно ограничить как строки, так и столбцы, к которым может получить доступ роль:

{
  "role": "auditor",
  "actions": [
    {
      "action": "read",
      "fields": {
        "include": ["id", "amount", "status"],
        "exclude": ["internalNotes"]
      },
      "policy": {
        "database": "@item.status eq 'completed'"
      }
    }
  ]
}

Ограничения

Ограничение Сведения
Нет create действия Инструкции INSERT не поддерживают предикаты WHERE
Нет execute действия Хранимые процедуры не принимают предикаты запросов
Отсутствие поддержки Azure Cosmos DB для NoSQL API NoSQL в настоящее время не поддерживает политики базы данных
Без именованных политик авторизации DAB не поддерживает именованные политики ASP.NET/HotChocolate-style

Troubleshooting

Утверждение не найдено (403 Запрещено)

Если запрос завершается ошибкой 403 Запрещено, проверьте следующее:

  • Утверждение существует в токене доступа
  • Имя утверждения полностью совпадает (с учетом регистра)
  • Поставщик удостоверений настроен для добавления требования

Политика не применяется

Если результаты не фильтруются:

  • Проверка соответствия имени роли значению заголовка X-MS-API-ROLE
  • Убедитесь, что для действия (чтение, обновление, удаление) определена политика.
  • Проверьте, настроена ли аутентификация и проходит ли запрос аутентификацию

синтаксические ошибки;

Если движок сообщает об ошибке синтаксического анализа политики:

  • Убедитесь, что выражение использует синтаксис OData (eq, ne, , andor)
  • Убедитесь, что имена полей соответствуют сопоставленным именам API (а не именам столбцов базы данных)
  • Убедитесь, что строковые значения заключены в одинарные кавычки