Filtry zabezpieczeń na potrzeby przycinania wyników w usłudze Azure AI Search

Usługa Azure AI Search nie zapewnia uprawnień na poziomie dokumentu i nie może różnić wyników wyszukiwania z poziomu tego samego indeksu według uprawnień użytkownika. Aby obejść ten problem, możesz utworzyć filtr, który przycina wyniki wyszukiwania na podstawie ciągu zawierającego grupę lub tożsamość użytkownika.

W tym artykule opisano wzorzec filtrowania zabezpieczeń, który obejmuje następujące kroki:

  • Złóż dokumenty źródłowe z wymaganą zawartością
  • Tworzenie pola dla identyfikatorów podmiotów zabezpieczeń
  • Wypychanie dokumentów do indeksu wyszukiwania na potrzeby indeksowania
  • Wykonywanie zapytań względem indeksu za pomocą search.in funkcji filter

Informacje o wzorcu filtru zabezpieczeń

Chociaż usługa Azure AI Search nie integruje się z podsystemami zabezpieczeń w celu uzyskania dostępu do zawartości w indeksie, wielu klientów, którzy mają wymagania dotyczące zabezpieczeń na poziomie dokumentu, odkryli, że filtry mogą spełniać ich potrzeby.

W usłudze Azure AI Search filtr zabezpieczeń jest zwykłym filtrem OData zawierającym lub wykluczającym wynik wyszukiwania na podstawie pasującej wartości, z tą różnicą, że w filtrze zabezpieczeń kryteria są ciągiem składającym się z podmiotu zabezpieczeń. Nie ma uwierzytelniania ani autoryzacji za pośrednictwem podmiotu zabezpieczeń. Podmiot zabezpieczeń to tylko ciąg używany w wyrażeniu filtru do uwzględnienia lub wykluczenia dokumentu z wyników wyszukiwania.

Istnieje kilka sposobów na osiągnięcie filtrowania zabezpieczeń. Jednym ze sposobów jest skomplikowane rozwarcie wyrażeń równości: na przykład Id eq 'id1' or Id eq 'id2', i tak dalej. Takie podejście jest podatne na błędy, trudne do utrzymania i w przypadkach, gdy lista zawiera setki lub tysiące wartości, spowalnia czas odpowiedzi zapytania o wiele sekund.

Lepszym rozwiązaniem jest użycie search.in funkcji dla filtrów zabezpieczeń zgodnie z opisem w tym artykule. Jeśli używasz search.in(Id, 'id1, id2, ...') wyrażenia równości zamiast wyrażenia równości, możesz oczekiwać czasu odpowiedzi podrzędnych.

Wymagania wstępne

  • Pole zawierające grupę lub tożsamość użytkownika musi być ciągiem z atrybutem, który można filtrować. Powinna to być kolekcja. Nie powinno zezwalać na wartości null.

  • Inne pola w tym samym dokumencie powinny zawierać zawartość dostępną dla tej grupy lub użytkownika. W poniższych dokumentach JSON pola "security_id" zawierają tożsamości używane w filtrze zabezpieczeń, a nazwa, wynagrodzenie i stan cywilny zostaną uwzględnione, jeśli tożsamość obiektu wywołującego pasuje do "security_id" dokumentu.

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

    Uwaga

    Proces pobierania identyfikatorów głównych i wstrzykiwania tych ciągów do dokumentów źródłowych, które mogą być indeksowane przez usługę Azure AI Search, nie jest opisany w tym artykule. Zapoznaj się z dokumentacją dostawcy usług tożsamości, aby uzyskać pomoc dotyczącą uzyskiwania identyfikatorów.

Tworzenie pola zabezpieczeń

W indeksie wyszukiwania w kolekcji pól potrzebne jest jedno pole zawierające tożsamość grupy lub użytkownika, podobne do fikcyjnego pola "security_id" w poprzednim przykładzie.

  1. Dodaj pole zabezpieczeń jako Collection(Edm.String). Upewnij się, że ma filterable on atrybut ustawiony na true wartość , aby wyniki wyszukiwania zostały filtrowane na podstawie dostępu, który ma użytkownik. Jeśli na przykład ustawisz group_ids dla dokumentu file_name wartość ["group_id1, group_id2"] "secured_file_b", tylko użytkownicy należący do identyfikatorów grup "group_id1" lub "group_id2" mają dostęp do odczytu do pliku.

    Ustaw atrybut pola retrievable na false , aby nie był zwracany w ramach żądania wyszukiwania.

  2. Indeksy wymagają klucza dokumentu. Pole "file_id" spełnia to wymaganie. Indeksy powinny również zawierać zawartość z możliwością wyszukiwania. Pola "file_name" i "file_description" reprezentują to w tym przykładzie.

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

Wypychanie danych do indeksu przy użyciu interfejsu API REST

Wyślij żądanie HTTP POST do kolekcji dokumentacji punktu końcowego adresu URL indeksu (zobacz Dokumenty — indeks). Treść żądania HTTP to renderowanie JSON dokumentów do indeksowania:

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

W treści żądania określ zawartość dokumentów:

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

Jeśli musisz zaktualizować istniejący dokument przy użyciu listy grup, możesz użyć merge akcji lub mergeOrUpload :

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

Stosowanie filtru zabezpieczeń w zapytaniu

Aby przyciąć dokumenty na group_ids podstawie dostępu, należy wydać zapytanie wyszukiwania z filtrem group_ids/any(g:search.in(g, 'group_id1, group_id2,...')) , w którym "group_id1, group_id2,..." to grupy, do których należy wystawca żądania wyszukiwania.

Ten filtr pasuje do wszystkich dokumentów, dla których group_ids pole zawiera jeden z podanych identyfikatorów. Aby uzyskać szczegółowe informacje na temat wyszukiwania dokumentów przy użyciu usługi Azure AI Search, możesz przeczytać artykuł Search Documents (Wyszukiwanie dokumentów).

W tym przykładzie pokazano, jak skonfigurować zapytanie przy użyciu żądania POST.

Wydaj żądanie 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]

Określ filtr w treści żądania:

{
   "filter":"group_ids/any(g:search.in(g, 'group_id1, group_id2'))"  
}

Należy pobrać dokumenty, w których group_ids znajdują się "group_id1" lub "group_id2". Innymi słowy, uzyskujesz dokumenty, do których wystawca żądań ma dostęp do odczytu.

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

Następne kroki

W tym artykule opisano wzorzec filtrowania wyników na podstawie tożsamości użytkownika i search.in() funkcji. Za pomocą tej funkcji można przekazać identyfikatory podmiotu zabezpieczeń dla żądanego użytkownika, aby był zgodny z identyfikatorami podmiotów zabezpieczeń skojarzonymi z każdym dokumentem docelowym. Po obsłużeniu żądania wyszukiwania funkcja filtruje wyniki wyszukiwania, search.in dla których żaden z podmiotów zabezpieczeń użytkownika nie ma dostępu do odczytu. Identyfikatory podmiotów zabezpieczeń mogą reprezentować takie elementy jak grupy zabezpieczeń, role, a nawet tożsamość użytkownika.

Aby uzyskać alternatywny wzorzec oparty na identyfikatorze Entra firmy Microsoft lub wrócić do innych funkcji zabezpieczeń, zobacz poniższe linki.