Condividi tramite


Filtri di sicurezza per limitare i risultati in Azure AI Search

Azure AI Search non fornisce autorizzazioni native a livello di documento e non può variare i risultati della ricerca dall'interno dello stesso indice in base alle autorizzazioni utente. Come soluzione alternativa, è possibile creare un filtro che taglia i risultati della ricerca sulla base di una stringa che contiene un gruppo o un'identità utente.

Questo articolo descrive un modello per il filtro della sicurezza con la procedura seguente:

  • Assemblare i documenti di origine con il contenuto richiesto
  • Creare un campo per gli identificatori dell'entità di sicurezza
  • Eseguire il push dei documenti nell'indice di ricerca per l'indicizzazione
  • Eseguire una query sull'indice con la funzione di filtro search.in

Si conclude con collegamenti a demo ed esempi che forniscono apprendimento pratico. Come prima cosa, è consigliabile esaminare questo articolo per comprendere il modello.

Informazioni sul modello di filtro di sicurezza

Anche se Azure AI Search non si integra con i sottosistemi di sicurezza per l'accesso al contenuto all'interno di un indice, molti clienti in possesso di requisiti di sicurezza a livello di documento trovano che i filtri siano in grado di soddisfare le proprie esigenze.

In Azure AI Search un filtro di sicurezza è un normale filtro OData che include o esclude un risultato di ricerca in base a una stringa costituita da un'entità di sicurezza. L'autenticazione o l'autorizzazione non sono disponibili tramite l'entità di sicurezza. L'entità è solo una stringa, usata in un'espressione filtro, per includere o escludere un documento dai risultati della ricerca.

Esistono diverse modalità per ottenere i filtri di protezione: Un modo è tramite una disgiunzione complessa di espressioni di uguaglianza: ad esempio Id eq 'id1' or Id eq 'id2' e così via. Questo approccio è soggetto a errori, difficili da gestire e nei casi in cui l'elenco contenga centinaia o migliaia di valori, rallenta il tempo di risposta della query di molti secondi.

Una soluzione migliore consiste nell'usare la funzione search.in per i filtri di sicurezza, come descritto in questo articolo. Se si usa search.in(Id, 'id1, id2, ...') al posto di un'espressione di uguaglianza, è possibile prevedere tempi di risposta in frazioni di secondo.

Prerequisiti

  • Campo stringa contenente un gruppo o un'identità utente, ad esempio un identificatore di oggetto Microsoft Entra.

  • Gli altri campi dello stesso documento devono fornire il contenuto accessibile a tale gruppo o utente. Nei documenti JSON seguenti i campi "security_id" contengono le identità usate in un filtro di sicurezza e il nome, lo stipendio e lo stato civile vengono inclusi se l'identità del chiamante corrisponde alla "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"
        } 
    }  
    

Creare il campo di sicurezza

Nell'indice di ricerca, all'interno della raccolta campi, è necessario un campo contenente il gruppo o l'identità utente, simile al campo fittizio "security_id" riportato nell'esempio precedente.

  1. Aggiungere un campo di sicurezza come Collection(Edm.String).

  2. Impostare l'attributo filterable del campo su true.

  3. Impostare l'attributo retrievable del campo su false in modo che non venga restituito come parte della richiesta di ricerca.

  4. Gli indici richiedono una chiave del documento. Il campo "file_id" soddisfa tale requisito.

  5. Gli indici devono contenere anche contenuto ricercabile e recuperabile. In questo esempio, i campi "file_name" e "file_description" ne sono la rappresentazione.

    Lo schema di indice seguente soddisfa i requisiti dei campi. I documenti indicizzati in Azure AI Search devono avere valori per tutti questi campi, incluso "group_ids". Per il documento con "secured_file_b" file_name, solo gli utenti che appartengono agli ID di gruppo "group_id1" o "group_id2" hanno l'accesso in lettura al file.

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

Push dei dati nell'indice tramite l'API REST

Popolare l'indice di ricerca con documenti che forniscono valori per ogni campo della raccolta campi, inclusi i valori per il campo di sicurezza. Azure AI Search non fornisce API o funzionalità per popolare il campo di sicurezza in modo specifico. Tuttavia, diversi esempi elencati alla fine di questo articolo illustrano le tecniche per popolare questo campo.

In Azure AI Search gli approcci per il caricamento dei dati sono:

  • operazione push o pull (indicizzatore) singola che importa i documenti popolati con tutti i campi
  • operazioni push o pull multiple. Se le operazioni di importazione secondarie hanno come destinazione l'identificatore di documento corretto, è possibile caricare i campi singolarmente tramite più importazioni.

L'esempio seguente mostra una singola richiesta HTTP POST alla raccolta docs dell'endpoint URL dell'indice ( vedere Documenti - Indice). Il corpo della richiesta HTTP è un rendering del report JSON dei documenti da indicizzare:

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 si desidera aggiornare un documento esistente con l'elenco di gruppi, è possibile usare l'azione merge o mergeOrUpload:

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

Applicare il filtro di sicurezza nella query

Al fine di tagliare i documenti in base all'accesso group_ids, è consigliabile eseguire una query di ricerca con un filtro group_ids/any(g:search.in(g, 'group_id1, group_id2,...')), in cui "group_id1, group_id2,..." sono i gruppi a cui appartiene l'emittente della richiesta di ricerca.

Questo filtro corrisponde a tutti i documenti per cui il campo group_ids contiene uno degli identificatori specificati. Per informazioni dettagliate sulla ricerca di documenti con Azure AI Search, è possibile leggere Cercare documenti.

Questo esempio illustra come configurare una query usando una richiesta POST.

Eseguire la richiesta HTTP POST, specificando il filtro nel corpo della richiesta:

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

È necessario riottenere i documenti in cui group_ids contiene "group_id1" o "group_id2". In altre parole, è possibile ottenere i documenti a cui il richiedente ha accesso in lettura.

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

Passaggi successivi

Questo articolo descrive un modello per filtrare i risultati in base all'identità utente e alla funzione search.in(). È possibile usare questa funzione per passare agli identificatori dell'entità di sicurezza per l'utente richiedente per confrontare gli identificatori dell'entità di sicurezza associati a ciascun documento di destinazione. Quando viene gestita una richiesta di ricerca, la funzione search.in filtra i risultati della ricerca per cui l'accesso in lettura non è consentito ad alcuna entità di sicurezza dell'utente. Gli identificatori dell'entità di sicurezza possono rappresentare oggetti quali i gruppi di sicurezza, i ruoli o persino l'identità dell'utente.

Per altri esempi, demo e video: