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.
Dodaj pole zabezpieczeń jako
Collection(Edm.String)
. Upewnij się, że mafilterable
on atrybut ustawiony natrue
wartość , aby wyniki wyszukiwania zostały filtrowane na podstawie dostępu, który ma użytkownik. Jeśli na przykład ustawiszgroup_ids
dla dokumentufile_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
nafalse
, aby nie był zwracany w ramach żądania wyszukiwania.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.