Compartir vía


Filtros de seguridad para restringir los resultados en Azure AI Search

La Búsqueda de Azure AI no proporciona permisos en el nivel de documento nativo y no puede variar los resultados de búsqueda desde dentro del mismo índice mediante permisos de usuario. Como solución alternativa, puede crear un filtro que restrinja los resultados de búsqueda en función de una cadena que contenga un grupo o una identidad de usuario.

En este artículo se describe un patrón para el filtrado de seguridad que incluye los pasos siguientes:

  • Ensamblar los documentos de origen con el contenido necesario
  • Crear un campo que contiene los identificadores de entidad de seguridad
  • Insertar los documentos en el índice de búsqueda para la indexación
  • Consulta del índice con la función de filtro de search.in

Concluye con vínculos a demostraciones y ejemplos que proporcionan aprendizaje práctico. Se recomienda revisar primero este artículo para comprender el patrón.

Acerca del patrón de filtro de seguridad

Aunque la Búsqueda de Azure AI no se integra con subsistemas de seguridad para acceder al contenido dentro de un índice, muchos clientes que tienen requisitos de seguridad en el nivel de documento han encontrado que los filtros pueden satisfacer sus necesidades.

En la Búsqueda de Azure AI, un filtro de seguridad es un filtro de OData normal que incluye o excluye un resultado de búsqueda basado en una cadena que consta de una entidad de seguridad. No hay autenticación ni autorización a través de la entidad de seguridad. La entidad de seguridad es simplemente una cadena, que se usa en una expresión de filtro, para incluir o excluir un documento de los resultados de la búsqueda.

Hay varias maneras de conseguir el filtrado de seguridad. Una forma es a través de una disyunción complicada de expresiones de igualdad: por ejemplo, Id eq 'id1' or Id eq 'id2', y así sucesivamente. Este enfoque es propenso a errores, es difícil de mantener y, en los casos en que la lista contiene cientos o miles de valores, ralentiza muchos segundos el tiempo de respuesta de consulta.

Una mejor solución es usar la función search.in para los filtros de seguridad, como se describe en este artículo. Si utiliza search.in(Id, 'id1, id2, ...') en lugar de una expresión de igualdad, puede esperar tiempos de respuesta de fracciones de segundo.

Requisitos previos

  • Campo de cadena que contiene un grupo o una identidad de usuario, como un identificador de objeto de Microsoft Entra.

  • Otros campos del mismo documento deben proporcionar un contenido accesible para ese grupo o usuario. En los siguientes documentos JSON, los campos "security_id" contienen identidades que se usan en un filtro de seguridad y el nombre, salario y estado civil se incluyen si la identidad del autor de la llamada coincide con el "security_id" del 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"
        } 
    }  
    

Creación del campo de seguridad

En el índice de búsqueda, dentro de la colección de campos, necesita un campo que contenga la identidad de grupo o usuario, similar al campo ficticio "security_id" del ejemplo anterior.

  1. Agregue un campo de seguridad como Collection(Edm.String).

  2. Establezca el atributo filterable del campo establecido en true.

  3. Establezca el atributo retrievable del campo en false para que no se devuelva como parte de la solicitud de búsqueda.

  4. Los índices requieren una clave de documento. El campo "file_id" cumple ese requisito.

  5. Los índices también deben contener contenido que se puede buscar y recuperar. Los campos "file_name" y "file_description" representan eso en este ejemplo.

    El siguiente esquema de índice cumple los requisitos de campo. Los documentos que indexe en la Búsqueda de Azure AI deben tener valores para todos estos campos, incluido el campo "group_ids". Para el documento con file_name "secured_file_b", solo los usuarios que pertenecen al grupo de identificadores "group_id1" o "group_id2" tienen acceso de lectura al archivo.

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

Inserción de datos en el índice mediante la API REST

Rellene el índice de búsqueda con documentos que proporcionen valores para cada campo de la colección de campos, incluidos los valores del campo de seguridad. La Búsqueda de Azure AI no proporciona API ni características para rellenar específicamente el campo de seguridad. Sin embargo, varios de los ejemplos enumerados al final de este artículo explican técnicas para rellenar este campo.

En la Búsqueda de Azure AI, los enfoques para cargar datos son:

  • Una sola operación de inserción o extracción (indexador) que importa documentos rellenados con todos los campos.
  • Varias operaciones de inserción o extracción. Siempre que las operaciones de importación secundarias tengan como destino el identificador de documento correcto, puede cargar campos individualmente a través de varias importaciones.

En el ejemplo siguiente se muestra una única solicitud HTTP POST a la colección de documentos del punto de conexión de la dirección URL del índice (consulte Documentos: índice). El cuerpo de la solicitud HTTP es una representación JSON de los documentos que se van a indexar:

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

Si necesita actualizar un documento existente con la lista de grupos, puede usar la acción merge o mergeOrUpload:

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

Aplicación del filtro de seguridad en la consulta

Para recortar documentos basados en el acceso group_ids, debe emitir una consulta de búsqueda con un filtro group_ids/any(g:search.in(g, 'group_id1, group_id2,...')), donde "group_id1, group_id2,..." son los grupos a los que pertenece el emisor de la solicitud de búsqueda.

Este filtro coincide con todos los documentos para los que el campo group_ids contiene uno de los identificadores especificados. Para obtener detalles completos sobre cómo buscar documentos con Azure AI Search, puede leer Búsqueda en documentos.

En este ejemplo se muestra cómo configurar la consulta mediante una solicitud POST.

Emita la solicitud HTTP POST y especifique el filtro en el cuerpo de la solicitud:

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

Debería obtener los documentos en que group_ids contenga "group_id1" o "group_id2". En otras palabras, obtendrá los documentos a los que el emisor de la solicitud tiene acceso de lectura.

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

Pasos siguientes

En este artículo se describe un patrón para filtrar los resultados en función de la identidad del usuario y la función search.in(). Puede usar esta función para pasar los identificadores de entidad de seguridad del usuario solicitante para que coincidan con los identificadores de entidad de seguridad asociados a cada documento de destino. Cuando se controla una solicitud de búsqueda, la función search.in filtra los resultados de la búsqueda para los que ninguna de las entidades de seguridad del usuario tiene acceso de lectura. Los identificadores de entidad de seguridad pueden representar elementos como los grupos de seguridad, los roles o incluso la identidad del usuario.

Para obtener más ejemplos, demostraciones y vídeos: