Partilhar via


Filtros de segurança para cortar resultados na Pesquisa de IA do Azure

O Azure AI Search não fornece permissões nativas no nível do documento e não pode variar os resultados da pesquisa de dentro do mesmo índice por permissões de usuário. Como solução alternativa, você pode criar um filtro que corta os resultados da pesquisa com base em uma cadeia de caracteres que contém uma identidade de grupo ou usuário.

Este artigo descreve um padrão para filtragem de segurança com as seguintes etapas:

  • Monte documentos de origem com o conteúdo necessário
  • Criar um campo para os identificadores principais
  • Enviar os documentos para o índice de pesquisa para indexação
  • Consultar o índice com a search.in função de filtro

Conclui com links para demonstrações e exemplos que fornecem aprendizagem prática. Recomendamos que leia este artigo primeiro para entender o padrão.

Sobre o padrão de filtro de segurança

Embora o Azure AI Search não se integre aos subsistemas de segurança para acesso ao conteúdo dentro de um índice, muitos clientes que têm requisitos de segurança em nível de documento descobrem que os filtros podem atender às suas necessidades.

No Azure AI Search, um filtro de segurança é um filtro OData regular que inclui ou exclui um resultado de pesquisa com base em uma cadeia de caracteres que consiste em uma entidade de segurança. Não há autenticação ou autorização através da entidade de segurança. O principal é apenas uma cadeia de caracteres, usada em uma expressão de filtro, para incluir ou excluir um documento dos resultados da pesquisa.

Há várias maneiras de obter filtragem de segurança. Uma maneira é através de uma disjunção complicada de expressões de igualdade: por exemplo, Id eq 'id1' or Id eq 'id2', e assim por diante. Essa abordagem é propensa a erros, difícil de manter e, nos casos em que a lista contém centenas ou milhares de valores, diminui o tempo de resposta da consulta em muitos segundos.

Uma solução melhor é usar a search.in função para filtros de segurança, conforme descrito neste artigo. Se você usar search.in(Id, 'id1, id2, ...') em vez de uma expressão de igualdade, você pode esperar tempos de resposta subsegundo.

Pré-requisitos

  • Um campo de cadeia de caracteres que contém uma identidade de grupo ou usuário, como um identificador de objeto do Microsoft Entra.

  • Outros campos no mesmo documento devem fornecer o conteúdo acessível a esse grupo ou usuário. Nos seguintes documentos JSON, os campos "security_id" contêm identidades usadas em um filtro de segurança, e o nome, salário e estado civil são incluídos se a identidade do chamador corresponder ao "security_id" do documento.

    {  
        "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"
        } 
    }  
    

Criar campo de segurança

No índice de pesquisa, dentro da coleção fields, você precisa de um campo que contenha a identidade do grupo ou do usuário, semelhante ao campo fictício "security_id" no exemplo anterior.

  1. Adicionar um campo de segurança como um Collection(Edm.String)arquivo .

  2. Defina o atributo do filterable campo definido como true.

  3. Defina o atributo do retrievable campo como false para que ele não seja retornado como parte da solicitação de pesquisa.

  4. Os índices requerem uma chave de documento. O campo "file_id" satisfaz este requisito.

  5. Os índices também devem conter conteúdo pesquisável e recuperável. Os campos "file_name" e "file_description" representam isso neste exemplo.

    O esquema de índice a seguir satisfaz os requisitos de campo. Os documentos indexados no Azure AI Search devem ter valores para todos esses campos, incluindo o "group_ids". Para o documento com file_name "secured_file_b", apenas os usuários que pertencem aos IDs de grupo "group_id1" ou "group_id2" têm acesso de leitura ao arquivo.

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

Envie dados por push para seu índice usando a API REST

Preencha seu índice de pesquisa com documentos que fornecem valores para cada campo na coleção de campos, incluindo valores para o campo de segurança. O Azure AI Search não fornece APIs ou recursos para preencher o campo de segurança especificamente. No entanto, vários dos exemplos listados no final deste artigo explicam técnicas para preencher este campo.

No Azure AI Search, as abordagens para carregar dados são:

  • Uma única operação push ou pull (indexador) que importa documentos preenchidos com todos os campos
  • Várias operações de push ou pull. Contanto que as operações de importação secundárias tenham como alvo o identificador de documento correto, você pode carregar campos individualmente por meio de várias importações.

O exemplo a seguir mostra uma única solicitação HTTP POST para a coleção de documentos do ponto de extremidade de URL do seu índice (consulte Documents - Index). O corpo da solicitação HTTP é uma renderização JSON dos documentos a serem indexados:

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"]
        }
    ]
}

Se precisar atualizar um documento existente com a lista de grupos, você pode usar a merge ação ou mergeOrUpload :

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

Aplicar o filtro de segurança na consulta

A fim de cortar documentos com base no group_ids acesso, você deve emitir uma consulta de pesquisa com um group_ids/any(g:search.in(g, 'group_id1, group_id2,...')) filtro, onde 'group_id1, group_id2,...' são os grupos aos quais pertence o emissor do pedido de pesquisa.

Este filtro corresponde a todos os documentos para os quais o group_ids campo contém um dos identificadores fornecidos. Para obter detalhes completos sobre como pesquisar documentos usando a Pesquisa de IA do Azure, você pode ler Pesquisar Documentos.

Este exemplo mostra como configurar a consulta usando uma solicitação POST.

Emita a solicitação HTTP POST, especificando o filtro no corpo da solicitação:

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'))"  
}

Você deve obter os documentos de volta onde group_ids contém "group_id1" ou "group_id2". Em outras palavras, você obtém os documentos aos quais o emissor da solicitação tem acesso de leitura.

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

Próximos passos

Este artigo descreve um padrão para filtrar resultados com base na identidade do usuário e na search.in() função. Você pode usar essa função para passar identificadores principais para que o usuário solicitante faça a correspondência com os identificadores principais associados a cada documento de destino. Quando uma solicitação de pesquisa é tratada, a função filtra os search.in resultados da pesquisa para os quais nenhuma das entidades do usuário tem acesso de leitura. Os identificadores principais podem representar coisas como grupos de segurança, funções ou até mesmo a própria identidade do usuário.

Para mais exemplos, demonstrações e vídeos: