Filtri di sicurezza per il taglio dei risultati in Ricerca di intelligenza artificiale di Azure

Ricerca di intelligenza artificiale di Azure non fornisce autorizzazioni 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 in base a una stringa contenente un gruppo o un'identità utente.

Questo articolo descrive un modello per il filtro della sicurezza che include i passaggi seguenti:

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

Informazioni sul modello di filtro di sicurezza

Anche se Ricerca di intelligenza artificiale di Azure non si integra con i sottosistemi di sicurezza per l'accesso al contenuto all'interno di un indice, molti clienti che hanno requisiti di sicurezza a livello di documento hanno scoperto che i filtri possono soddisfare le proprie esigenze.

In Ricerca di intelligenza artificiale di Azure un filtro di sicurezza è un normale filtro OData che include o esclude un risultato di ricerca in base a un valore corrispondente, ad eccezione del fatto che in un filtro di sicurezza, i criteri sono 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 di filtro, per includere o escludere un documento dai risultati della ricerca.

Esistono diversi modi per ottenere il filtro di sicurezza. Un modo consiste nell'eseguire una complessa disgiunzione delle 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 search.in funzione per i filtri di sicurezza, come descritto in questo articolo. Se si usa search.in(Id, 'id1, id2, ...') invece di un'espressione di uguaglianza, è possibile prevedere tempi di risposta secondari.

Prerequisiti

  • Il campo contenente un gruppo o un'identità utente deve essere una stringa con l'attributo filtrabile. Deve essere una raccolta. Non deve consentire i valori Null.

  • 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 identità usate in un filtro di sicurezza e il nome, lo stipendio e lo stato coniugale verranno inclusi se l'identità del chiamante corrisponde al "security_id" del documento.

    {  
        "Employee-1": {  
            "id": "100-1000-10-1-10000-1",
            "name": "Abram",   
            "salary": 75000,   
            "married": true,
            "security_id": "10011"
        },
        "Employee-2": {  
            "id": "200-2000-20-2-20000-2",
            "name": "Adams",   
            "salary": 75000,   
            "married": true,
            "security_id": "20022"
        } 
    }  
    

    Nota

    Il processo di recupero degli identificatori principali e l'inserimento di tali stringhe nei documenti di origine che è possibile indicizzare da Ricerca di intelligenza artificiale di Azure non è trattato in questo articolo. Per informazioni su come ottenere gli identificatori, vedere la documentazione del provider di servizi di identità.

Creare il campo di sicurezza

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

  1. Aggiungere un campo di sicurezza come .Collection(Edm.String) Assicurarsi che abbia un filterable attributo impostato su true in modo che i risultati della ricerca vengano filtrati in base all'accesso dell'utente. Ad esempio, se si imposta il group_ids campo su ["group_id1, group_id2"] per il documento con file_name "secured_file_b", solo gli utenti che appartengono agli ID gruppo "group_id1" o "group_id2" hanno accesso in lettura al file.

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

  2. Gli indici richiedono una chiave del documento. Il campo "file_id" soddisfa tale requisito. Gli indici devono contenere anche contenuto ricercabile. I campi "file_name" e "file_description" rappresentano che in questo esempio.

    POST https://[search service].search.windows.net/indexes/securedfiles/docs/index?api-version=2023-11-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 }
         ]
     }
    

Eseguire il push dei dati nell'indice usando l'API REST

Inviare una richiesta HTTP POST alla raccolta di documenti dell'endpoint URL dell'indice (vedere Documents - Index). Il corpo della richiesta HTTP è un rendering JSON dei documenti da indicizzare:

POST https://[search service].search.windows.net/indexes/securedfiles/docs/index?api-version=2023-11-01

Nel corpo della richiesta, specificare il contenuto dei documenti:

{
    "value": [
        {
            "@search.action": "upload",
            "file_id": "1",
            "file_name": "secured_file_a",
            "file_description": "File access is restricted to the 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 Ricerca di intelligenza artificiale di Azure, è possibile leggere Cerca documenti.

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

Inviare la richiesta HTTP POST:

POST https://[service name].search.windows.net/indexes/securedfiles/docs/search?api-version=2020-06-30
Content-Type: application/json  
api-key: [admin or query key]

Specificare il filtro nel corpo della richiesta:

{
   "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 search.in() funzione. È 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 un modello alternativo basato sull'ID Microsoft Entra o per rivedere altre funzionalità di sicurezza, vedere i collegamenti seguenti.