Фильтры безопасности для обрезки результатов поиска ИИ Azure с помощью клиентов и удостоверений Microsoft Entra

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

В этой статье рассматриваются следующие задачи:

  • Создание групп и пользователей Microsoft Entra
  • связывание пользователя с созданной группой;
  • кэширование новых групп;
  • индексация документов со связанными группами;
  • отправка запроса на поиск с помощью фильтра идентификаторов групп.

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

Индекс в службе "Поиск ИИ Azure" должен иметь поле безопасности для хранения списка удостоверений групп с доступом на чтение к документу. Этот вариант использования предполагает прямое соответствие между защищаемым элементом (например, заявление на вступление в колледж конкретного человека) и полем безопасности, в котором указывается, кто имеет доступ к этому элементу (персонал приемной комиссии).

Для создания пользователей, групп и ассоциаций необходимо иметь разрешения администратора Microsoft Entra (владелец или администратор).

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

Регистрация приложения с помощью идентификатора Microsoft Entra

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

  1. В портал Azure найдите клиент Идентификатора Microsoft Entra.

  2. В области Управление слева выберите Регистрация приложений, а затем — Новая регистрация.

  3. Присвойте регистрации имя, возможно, имя, аналогичное имени приложения поиска. Дополнительные сведения о других необязательных свойствах см. в этой статье .

  4. Выберите Зарегистрировать.

  5. После создания регистрации приложения скопируйте идентификатор приложения (клиента). Вам потребуется предоставить эту строку приложению.

    Если вы выполняете шаг через DotNetHowToSecurityTrimming, вставьте это значение в файл app.config .

  6. Скопируйте идентификатор каталога (клиента).

    Screenshot of the application ID in the Essentials section.

  7. В области слева выберите Разрешения API, а затем — Добавить разрешение.

  8. Выберите Microsoft Graph, а затем — Делегированные разрешения.

  9. Найдите и добавьте следующие делегированные разрешения:

    • Directory.ReadWrite.All;
    • Group.ReadWrite.All;
    • User.ReadWrite.All

    Microsoft Graph предоставляет API, который обеспечивает программный доступ к идентификатору Microsoft Entra через REST API. Пример кода в этом пошаговом руководстве использует разрешения для вызова API Microsoft Graph, чтобы создавать группы, пользователей и ассоциации. API также используются для кэширования идентификаторов групп для более быстрой фильтрации.

  10. Выберите "Предоставить согласие администратора" для клиента , чтобы завершить процесс согласия.

Создание пользователей и групп

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

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

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

Шаг 1: Создание группы

private static Dictionary<Group, List<User>> CreateGroupsWithUsers(string tenant)
{
    Group group = new Group()
    {
        DisplayName = "My First Prog Group",
        SecurityEnabled = true,
        MailEnabled = false,
        MailNickname = "group1"
    };

Шаг 2: Создание пользователя

User user1 = new User()
{
    GivenName = "First User",
    Surname = "User1",
    MailNickname = "User1",
    DisplayName = "First User",
    UserPrincipalName = String.Format("user1@{0}", tenant),
    PasswordProfile = new PasswordProfile() { Password = "********" },
    AccountEnabled = true
};

Шаг 3. Связывание пользователя и групп

List<User> users = new List<User>() { user1, user2 };
Dictionary<Group, List<User>> groups = new Dictionary<Group, List<User>>() { { group, users } };

Шаг 4. Кэширование идентификаторов групп

При необходимости, чтобы уменьшить задержку в сети, можно кэшировать связи групп пользователей, чтобы при выдаче поискового запроса группы группы возвращались из кэша, сохраняя циклический обход в идентификатор Microsoft Entra. С помощью API пакетной службы Microsoft Entra можно отправить один http-запрос с несколькими пользователями и создать кэш.

Microsoft Graph может обрабатывать большое число запросов. Если возникает огромное количество запросов, Microsoft Graph отклоняет запрос с кодом состояния HTTP 429. Дополнительные сведения см. в статье Руководство по регулированию Microsoft Graph.

Индексирование документа с разрешенными группами

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

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

В гипотетическом примере текст запроса PUT по индексу поиска ИИ Azure будет включать эссе или расшифровку колледжа кандидата вместе с идентификатором группы с разрешением на просмотр этого содержимого.

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

private static void IndexDocuments(string indexName, List<string> groups)
{
    IndexDocumentsBatch<SecuredFiles> batch = IndexDocumentsBatch.Create(
        IndexDocumentsAction.Upload(
            new SecuredFiles()
            {
                FileId = "1",
                Name = "secured_file_a",
                GroupIds = new[] { groups[0] }
            }),
              ...
            };

IndexDocumentsResult result = searchClient.IndexDocuments(batch);

Отправка поискового запроса

В целях применения фильтров безопасности значения в поле безопасности в индексе являются статическими значениями, используемыми для включения или исключения документов в результатах поиска. Например, если идентификатор группы для приемов имеет значение "A11B22C33D44-E55F66G77-H88I99JKK", все документы в индексе поиска Azure ИИ, имеющие этот идентификатор в поле безопасности, включены (или исключены) в результаты поиска, отправляемые обратно вызывающей стороне.

Чтобы фильтровать документы, возвращаемые в результатах поиска, по группам для пользователя, выполняющего запрос, сделайте следующее.

Шаг 1. Получение идентификаторов группы пользователя

Если группы пользователей еще не кэшировались или срок действия кэша истек, отправьте запрос групп .

private static async void RefreshCache(IEnumerable<User> users)
{
    HttpClient client = new HttpClient();
    var userGroups = await _microsoftGraphHelper.GetGroupsForUsers(client, users);
    _groupsCache = new ConcurrentDictionary<string, List<string>>(userGroups);
}

Шаг 2. Составление поискового запроса

Предположим, что у вас есть членство в группах пользователей. Это позволяет отправить поисковой запрос с соответствующими значениями фильтра.

private static void SearchQueryWithFilter(string user)
{
    // Using the filter below, the search result will contain all documents that their GroupIds field   
    // contain any one of the Ids in the groups list
    string filter = String.Format("groupIds/any(p:search.in(p, '{0}'))", string.Join(",", String.Join(",", _groupsCache[user])));
    SearchOptions searchOptions =
        new SearchOptions()
        {
            Filter = filter
        };
    searchOptions.Select.Add("name");

    SearchResults<SecuredFiles> results = searchClient.Search<SecuredFiles>("*", searchOptions);

    Console.WriteLine("Results for groups '{0}' : {1}", _groupsCache[user], results.GetResults().Select(r => r.Document.Name));
}

Шаг 3. Обработка результатов

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

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

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