Udostępnij za pośrednictwem


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

Usługa Azure AI Search nie zapewnia natywnych 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ń, wykonując następujące czynności:

  • 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

Zawiera on linki do pokazów i przykładów, które zapewniają praktyczne uczenie się. Zalecamy zapoznanie się z tym artykułem najpierw, aby zrozumieć wzorzec.

Informacje o wzorcu filtru zabezpieczeń

Mimo że 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, uważają, że filtry mogą spełniać ich potrzeby.

W usłudze Azure AI Search filtr zabezpieczeń to zwykły filtr OData zawierający lub wykluczający wynik wyszukiwania na podstawie ciągu składającego 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 ciągu zawierające tożsamość grupy lub użytkownika, takie jak identyfikator obiektu Entra firmy Microsoft.

  • 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 są uwzględniane, jeśli tożsamość obiektu wywołującego pasuje do "security_id" dokumentu.

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

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).

  2. Ustaw atrybut pola filterable na truewartość .

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

  4. Indeksy wymagają klucza dokumentu. Pole "file_id" spełnia to wymaganie.

  5. Indeksy powinny również zawierać zawartość z możliwością wyszukiwania i pobierania. Pola "file_name" i "file_description" reprezentują to w tym przykładzie.

    Poniższy schemat indeksu spełnia wymagania dotyczące pól. Dokumenty indeksujące w usłudze Azure AI Search powinny zawierać wartości dla wszystkich tych pól, w tym "group_ids". W przypadku dokumentu z file_name "secured_file_b" tylko użytkownicy należący do identyfikatorów grup "group_id1" lub "group_id2" mają dostęp do odczytu do pliku.

    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

Zapełnij indeks wyszukiwania dokumentami, które udostępniają wartości dla każdego pola w kolekcji pól, w tym wartości pola zabezpieczeń. Usługa Azure AI Search nie udostępnia interfejsów API ani funkcji do wypełniania pola zabezpieczeń specjalnie. Jednak kilka przykładów wymienionych na końcu tego artykułu wyjaśnia techniki wypełniania tego pola.

W usłudze Azure AI Search metody ładowania danych to:

  • Pojedyncza operacja wypychania lub ściągania (indeksatora), która importuje dokumenty wypełnione wszystkimi polami
  • Wiele operacji wypychania lub ściągania. Tak długo, jak operacje importu pomocniczego są przeznaczone dla odpowiedniego identyfikatora dokumentu, można ładować pola indywidualnie za pomocą wielu importów.

Poniższy przykład przedstawia pojedyncze żądanie HTTP POST do kolekcji dokumentów 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
{
    "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"]
        }
    ]
}

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, określając filtr w treści żądania:

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

{
   "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ć więcej przykładów, pokazów i filmów wideo: