Partilhar via


Filtros de segurança para cortar resultados da Pesquisa do Azure AI usando o MAzure Ative Directory

Este artigo demonstra como usar identidades de segurança junto com filtros na Pesquisa de IA do Azure para cortar resultados de pesquisa com base na associação ao grupo de usuários.

Este artigo abrange as seguintes tarefas:

  • Criar grupos e usuários
  • Associar o usuário ao grupo que você criou
  • Armazenar em cache os novos grupos
  • Indexar documentos com grupos associados
  • Emitir uma solicitação de pesquisa com filtro de identificadores de grupo

Pré-requisitos

Seu índice no Azure AI Search deve ter um campo de segurança para armazenar a lista de identidades de grupo com acesso de leitura ao documento. Este caso de uso pressupõe uma correspondência um-para-um entre um item protegível (como o aplicativo de faculdade de um indivíduo) e um campo de segurança especificando quem tem acesso a esse item (pessoal de admissão).

Você deve ter permissões de administrador de locatário (Proprietário ou administrador) para criar usuários, grupos e associações.

Seu aplicativo também deve ser registrado como um aplicativo multilocatário, conforme descrito no procedimento a seguir.

Registrar seu aplicativo com o Azure Ative Directory

Esta etapa integra seu aplicativo ao Azure Ative Directory com a finalidade de aceitar entradas de contas de usuário e grupo. Se você não for um administrador de locatário em sua organização, talvez seja necessário criar um novo locatário para executar as etapas a seguir.

  1. No portal do Azure, localize o locatário do Azure Ative Directory.

  2. À esquerda, em Gerir, selecione Registos de aplicações e, em seguida, selecione Novo registo.

  3. Dê ao registro um nome, talvez um nome semelhante ao nome do aplicativo de pesquisa. Consulte este artigo para obter informações sobre outras propriedades opcionais.

  4. Selecione Registar.

  5. Depois que o registro do aplicativo for criado, copie a ID do aplicativo (cliente). Você precisará fornecer essa cadeia de caracteres ao seu aplicativo.

    Se você estiver passando pelo DotNetHowToSecurityTrimming, cole esse valor no arquivo app.config .

  6. Copie o ID do diretório (locatário).

  7. À esquerda, selecione Permissões de API e, em seguida, selecione Adicionar uma permissão.

  8. Selecione Microsoft Graph e, em seguida, selecione Permissões delegadas.

  9. Procure e adicione as seguintes permissões delegadas:

    • Directory.ReadWrite.All
    • Grupo.ReadWrite.All
    • Usuário.ReadWrite.All

    O Microsoft Graph fornece uma API que permite acesso programático ao Azure Ative Directory por meio de uma API REST. O exemplo de código para este passo a passo usa as permissões para chamar a API do Microsoft Graph para criar grupos, usuários e associações. As APIs também são usadas para armazenar em cache identificadores de grupo para uma filtragem mais rápida.

  10. Selecione Conceder consentimento de administrador para o locatário concluir o processo de consentimento.

Criar usuários e grupos

Se estiver a adicionar pesquisa a uma aplicação estabelecida, poderá ter identificadores de utilizador e grupo existentes no Azure Ative Directory. Nesse caso, você pode pular as próximas três etapas.

No entanto, se você não tiver usuários existentes, poderá usar as APIs do Microsoft Graph para criar as entidades de segurança. Os trechos de código a seguir demonstram como gerar identificadores, que se tornam valores de dados para o campo de segurança em seu índice do Azure AI Search. Em nosso hipotético pedido de admissão em faculdades, esses seriam os identificadores de segurança para a equipe de admissão.

A associação de usuários e grupos pode ser muito fluida, especialmente em grandes organizações. O código que cria identidades de usuário e grupo deve ser executado com frequência suficiente para captar alterações na associação à organização. Da mesma forma, seu índice do Azure AI Search requer um cronograma de atualização semelhante para refletir o status atual dos usuários e recursos permitidos.

Etapa 1: Criar grupo

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

Etapa 2: Criar usuário

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

Etapa 3: Associar usuário e grupo

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

Etapa 4: Armazenar em cache os identificadores de grupos

Opcionalmente, para reduzir a latência da rede, você pode armazenar em cache as associações de grupo de usuários para que, quando uma solicitação de pesquisa for emitida, os grupos sejam retornados do cache, salvando uma viagem de ida e volta. Você pode usar a API em lote para enviar uma única solicitação Http com vários usuários e criar o cache.

O Microsoft Graph foi concebido para processar um volume muito elevado de pedidos. Se ocorrer um número esmagador de solicitações, o Microsoft Graph falhará a solicitação com o código de status HTTP 429. Para obter mais informações, consulte Limitação do Microsoft Graph.

Documento de índice com seus grupos permitidos

As operações de consulta no Azure AI Search são executadas em um índice do Azure AI Search. Nesta etapa, uma operação de indexação importa dados pesquisáveis para um índice, incluindo os identificadores usados como filtros de segurança.

O Azure AI Search não autentica identidades de usuário nem fornece lógica para estabelecer qual conteúdo um usuário tem permissão para exibir. O caso de uso para filtragem de segurança pressupõe que você forneça a associação entre um documento confidencial e o identificador de grupo que tem acesso a esse documento, importado intacto para um índice de pesquisa.

No exemplo hipotético, o corpo da solicitação PUT em um índice do Azure AI Search incluiria o ensaio ou transcrição da faculdade de um candidato, juntamente com o identificador de grupo com permissão para exibir esse conteúdo.

No exemplo genérico usado no exemplo de código para esta explicação passo a passo, a ação de índice pode ter a seguinte aparência:

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

Emitir um pedido de pesquisa

Para fins de filtragem de segurança, os valores no campo de segurança no índice são valores estáticos usados para incluir ou excluir documentos nos resultados da pesquisa. Por exemplo, se o identificador de grupo para Admissões for "A11B22C33D44-E55F66G77-H88I99JKK", todos os documentos em um índice do Azure AI Search com esse identificador no campo de segurança serão incluídos (ou excluídos) nos resultados da pesquisa enviados de volta ao chamador.

Para filtrar documentos retornados nos resultados da pesquisa com base nos grupos do usuário que emite a solicitação, revise as etapas a seguir.

Etapa 1: Recuperar identificadores de grupo do usuário

Se os grupos do usuário ainda não estiverem armazenados em cache ou se o cache tiver expirado, emita a solicitação de grupos .

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

Etapa 2: compor a solicitação de pesquisa

Supondo que você tenha a associação de grupos do usuário, você pode emitir a solicitação de pesquisa com os valores de filtro apropriados.

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

Etapa 3: Manipular os resultados

A resposta inclui uma lista filtrada de documentos, que consiste naqueles que o usuário tem permissão para exibir. Dependendo de como você constrói a página de resultados da pesquisa, convém incluir pistas visuais para refletir o conjunto de resultados filtrados.

Conclusões

Neste passo a passo, você aprendeu um padrão para usar entradas de usuário para filtrar documentos nos resultados da Pesquisa do Azure AI, cortando os resultados de documentos que não correspondem ao filtro fornecido na solicitação.