Бөлісу құралы:


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

Поиск ИИ Azure не предоставляет собственные разрешения на уровне документа и не может отличать результаты поиска в одном индексе по разрешениям пользователя. В качестве обходного решения можно создать фильтр, который обрезает результаты поиска на основе строки, содержащей группу или удостоверение пользователя.

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

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

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

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

Хотя поиск ИИ Azure не интегрируется с подсистемами безопасности для доступа к содержимому в индексе, многие клиенты, у которых есть требования к безопасности на уровне документа, считают, что фильтры могут соответствовать их потребностям.

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

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

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

Необходимые компоненты

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

  • Другие поля в том же документе должны предоставлять содержимое, доступное для этой группы или пользователя. В следующих документах 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. Задайте атрибут false поля retrievable таким образом, чтобы он не возвращался в рамках поискового запроса.

  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=2024-07-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 не предоставляет API-интерфейсы или функции для заполнения поля безопасности в частности. Однако несколько примеров, перечисленных в конце этой статьи, объясняют методы заполнения этого поля.

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

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

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

POST https://[search service].search.windows.net/indexes/securedfiles/docs/index?api-version=2024-07-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" можно прочитать в документах поиска.

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

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

POST https://[service name].search.windows.net/indexes/securedfiles/docs/search?api-version=2024-07-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 отфильтровывает результаты поиска, отклоняя файлы, для которых ни один из субъектов-пользователей не имеет доступа на чтение. Идентификаторы субъектов могут представлять группы безопасности, роли или даже удостоверение пользователя.

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