Фильтры безопасности для обрезки результатов поиска ИИ Azure

Для решений поиска, которые не могут использовать встроенную поддержку списка управления доступом (ACL) для авторизации на уровне документа, поиск Azure AI поддерживает создание фильтра, который обрезает результаты поиска на основе строки, содержащей группу или удостоверение пользователя.

В этой статье описывается шаблон фильтрации безопасности с помощью следующих действий.

  • Сборка исходных документов с необходимым содержимым, включая строку для хранения идентификатора
  • Создание поля в индексе поиска для основных идентификаторов
  • Отправка документов в индекс поиска для индексирования
  • Запросить индекс с помощью функции фильтрации search.in

Он завершается ссылками на демонстрации и примеры, которые предоставляют практические знания. Мы рекомендуем сначала ознакомиться с этой статьей, чтобы понять шаблон.

Сведения о шаблоне фильтра безопасности

Шаблон фильтра безопасности имитирует авторизацию на уровне документа с помощью обычного фильтра OData, который включает или исключает результаты поиска на основе строки, состоящей из объекта безопасности. Проверка подлинности или авторизация не выполняется через субъект безопасности. Субъект — это только строка, используемая в выражении фильтра, для включения или исключения документа из результатов поиска.

Существует несколько способов фильтрации безопасности. Один из способов заключается в сложной дисъюнкции выражений равенства: например, Id eq 'id1' or Id eq 'id2', и т. д. Это ненадежный подход, его трудно поддерживать, а в тех случаях, когда список содержит сотни или тысячи значений, замедляется время ответа на запрос (в секундах).

Лучшее решение использует функцию search.in для фильтров безопасности, как описано в этой статье. Если вы используете search.in(Id, 'id1, id2, ...') вместо выражения равенства, вы можете ожидать несекундное время отклика.

Предварительные требования

  • Строковое поле, содержащее идентификатор группы или пользователя, например, объектный идентификатор Microsoft Entra ID.

  • Другие поля в том же документе должны предоставлять содержимое, доступное для этой группы или пользователя. В следующих документах JSON поля "security_id" содержат идентификаторы, используемые в фильтре безопасности, а имя, зарплата и семейное состояние включаются, если идентификатор вызывающего соответствует "security_id" документа.

    {  
        "Employee-1": {  
            "employee_id": "100-1000-10-1-10000-1",
            "name": "Abram",   
            "salary": 75000,   
            "married": true,
            "security_id": "alphanumeric-object-id-for-employee-1"
        },
        "Employee-2": {  
            "employee_id": "200-2000-20-2-20000-2",
            "name": "Adams",   
            "salary": 75000,   
            "married": true,
            "security_id": "alphanumeric-object-id-for-employee-2"
        } 
    }  
    

Создание поля безопасности

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

  1. Добавьте поле безопасности в виде Collection(Edm.String).

  2. Задайте для поля filterable атрибут true.

  3. Задайте атрибут retrievable поля false таким образом, чтобы он не возвращался в рамках поискового запроса.

  4. Для индексов требуется ключ документа. Поле "file_id" удовлетворяет требованиям.

  5. Индексы также должны содержать искомое и извлекаемое содержимое. Поля "file_name" и "file_description" представляют это в этом примере.

    Следующая схема индекса удовлетворяет требованиям к полю. Документы, индексы которых вы индексируете в поиске ИИ Azure, должны иметь значения для всех этих полей, включая "group_ids". В документе с file_name "secured_file_b" только пользователи, принадлежащие идентификаторам групп "group_id1" или "group_id2", имеют доступ на чтение к файлу.

    POST https://[search service].search.windows.net/indexes/securedfiles/docs/index?api-version=2025-09-01
    {
         "name": "securedfiles",  
         "fields": [
             {"name": "file_id", "type": "Edm.String", "key": true, "searchable": false },
             {"name": "file_name", "type": "Edm.String", "searchable": true },
             {"name": "file_description", "type": "Edm.String", "searchable": true },
             {"name": "group_ids", "type": "Collection(Edm.String)", "filterable": true, "retrievable": false }
         ]
     }
    

Отправка данных в индекс с помощью REST API

Заполните индекс поиска документами, которые предоставляют значения для каждого поля в коллекции полей, включая значения для поля безопасности. Поиск Azure AI не предоставляет API или функции для заполнения поля безопасности. Однако несколько примеров, перечисленных в конце этой статьи, объясняют методы заполнения этого поля.

В службе "Поиск ИИ Azure" подходы к загрузке данных:

  • Одна операция добавления или извлечения (индексатора), которая импортирует документы, включающие все поля
  • Несколько операций отправки или извлечения. Если вторичные операции импорта предназначены для правильного идентификатора документа, вы можете загружать поля по отдельности с помощью нескольких импортов.

В следующем примере показан однократный HTTP-запрос POST в коллекцию документов конечной точки URL для вашего индекса (см. Документы — Индекс). Тело HTTP-запроса представляет собой документы в формате JSON, которые необходимо индексировать.

POST https://[search service].search.windows.net/indexes/securedfiles/docs/index?api-version=2025-09-01
{
    "value": [
        {
            "@search.action": "upload",
            "file_id": "1",
            "file_name": "secured_file_a",
            "file_description": "File access is restricted to Human Resources.",
            "group_ids": ["group_id1"]
        },
        {
            "@search.action": "upload",
            "file_id": "2",
            "file_name": "secured_file_b",
            "file_description": "File access is restricted to Human Resources and Recruiting.",
            "group_ids": ["group_id1", "group_id2"]
        },
        {
            "@search.action": "upload",
            "file_id": "3",
            "file_name": "secured_file_c",
            "file_description": "File access is restricted to Operations and Logistics.",
            "group_ids": ["group_id5", "group_id6"]
        }
    ]
}

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

{
    "value": [
        {
            "@search.action": "mergeOrUpload",
            "file_id": "3",
            "group_ids": ["group_id7", "group_id8", "group_id9"]
        }
    ]
}

Применение фильтра безопасности в запросе

Чтобы сократить количество документов на основе доступа по group_ids, выполните поисковой запрос с использованием фильтра group_ids/any(g:search.in(g, 'group_id1, group_id2,...')) (где "group_id1 group_id2,..." — это группы, к которым принадлежит инициатор запроса).

Этот фильтр соответствует всем документам, для которых поле group_ids содержит один из заданных идентификаторов. Полные сведения о поиске документов с помощью Поиск с использованием ИИ Azure можно найти в разделе "Search Documents".

В этом примере показано, как настроить запрос с помощью запроса POST.

Выполните HTTP-запрос POST, указав фильтр в тексте запроса:

POST https://[service name].search.windows.net/indexes/securedfiles/docs/search?api-version=2025-09-01

{
   "filter":"group_ids/any(g:search.in(g, 'group_id1, group_id2'))"  
}

Будут возвращены документы, в поле group_ids которых содержится "group_id1" или "group_id2". Другими словами, вы получаете документы, к которым у инициатора запроса есть доступ на чтение.

{
 [
   {
    "@search.score":1.0,
     "file_id":"1",
     "file_name":"secured_file_a",
   },
   {
     "@search.score":1.0,
     "file_id":"2",
     "file_name":"secured_file_b"
   }
 ]
}

Следующие шаги

В этой статье описывается шаблон фильтрации результатов на основе удостоверения пользователя и search.in() функции. Эту функцию можно использовать для передачи идентификаторов субъектов запрашивающего пользователя, чтобы сопоставить их с идентификаторами субъектов, связанными с каждым целевым документом. Во время обработки поискового запроса функция search.in отфильтровывает результаты поиска, исключая те, к которым ни один из принципалов пользователя не имеет доступа для чтения. Основные идентификаторы могут представлять группы безопасности, роли или даже удостоверение пользователя.

Дополнительные примеры, демонстрации и видео: