共用方式為


在 Azure AI 搜尋服務中進行安全性篩選以調整結果

Azure AI 搜尋服務不提供原生文件層級權限,且無法透過使用者權限變更相同索引中的搜尋結果。 作為因應措施,您可以建立篩選條件,根據包含群組或使用者身分識別的字串來調整搜尋結果。

本文說明安全性篩選的模式,包含下列步驟:

  • 使用必要內容組合來源文件
  • 建立主體識別碼的欄位
  • 將文件推送至搜尋索引以編製索引
  • 使用 search.in 篩選函式查詢索引

最後會提供實際操作學習的示範和範例連結。 建議您先檢閱本文以了解模式。

關於安全性篩選模式

雖然 Azure AI 搜尋服務並未與安全性子系統整合以支援存取索引內的內容,但許多具有文件層級安全性需求的客戶發現篩選可滿足其需求。

在 Azure AI 搜尋服務中,安全性篩選屬於一般 OData 篩選,其根據包含安全性主體的字串來包含或排除搜尋結果。 沒有透過安全性主體的驗證或授權。 主體只是用於篩選條件運算式中的字串,可包含或排除搜尋結果中的文件。

有數種方法能夠實現安全性篩選。 其中一種方式,便是透過複雜的等號比較運算式分離:例如 Id eq 'id1' or Id eq 'id2' 等等。 此作法很容易發生錯誤且難以維護,若清單包含數以百計或千計的值,則會使查詢回應時間慢上數秒鐘。

如本文所述,針對安全性篩選使用 search.in 函式會是更好的解決方案。 若您使用 search.in(Id, 'id1, id2, ...') 取代等號比較運算式,則僅需不到一秒鐘的回應時間。

必要條件

  • 包含群組或使用者身分識別的字串欄位,例如Microsoft Entra 物件識別碼。

  • 同一文件中的其他欄位應提供該群組或使用者可存取的內容。 在下列 JSON 文件中,"security_id" 欄位包含安全性篩選中使用的身分識別,如果呼叫者的身分識別碼合文件的“security_id”,則會包含姓名、薪資和婚姻狀況。

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

建立安全性欄位

在搜尋索引的欄位集合中,您需要一個包含群組或使用者身分識別的欄位,類似於上一個範例中的虛構 "security_id" 欄位。

  1. 新增安全性欄位為 Collection(Edm.String)

  2. 將欄位的 filterable 屬性設定為 true

  3. 將欄位的 retrievable 屬性設為 false,其便不會作為搜尋要求的一部分傳回。

  4. 索引都需要文件索引鍵。 "file_id" 欄位符合該需求。

  5. 索引也應包含可搜尋和可擷取的內容。 "file_name" 和 "file_description" 欄位代表本例中可搜尋的內容。

    下列索引架構符合欄位需求。 您在 Azure AI 搜尋服務上編製索引的文件應該包含這些欄位的值,包括 "group_ids"。 針對具有 file_name "secured_file_b" 的文件,僅有屬於 "group_id1" 或 "group_id2" 群組識別碼的使用者才具備該檔案的讀取權限。

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

使用 REST API 將資料推送至索引

透過提供欄位集合中每個欄位值的文件 (包括安全性欄位的值) 以填入搜尋索引中。 Azure AI 搜尋服務不會特別提供 API 或功能來填入安全性欄位。 不過,本文結尾所列的數個範例會說明填入此欄位的技巧。

在 Azure AI 搜尋服務中,載入資料的方法如下:

  • 透過單一推送或提取 (索引子) 作業匯入已填入所有欄位的文件
  • 多個推送或提取作業。 只要次要匯入作業以正確的文件識別碼為目標,您就可以透過多個匯入來個別載入欄位。

下列範例顯示索引 URL 端點文件集合的單一 HTTP POST 要求 (請參閱文件 - 索引 (部分機器翻譯))。 HTTP 要求主體是要編製索引的文件 JSON 轉譯:

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

若您需要透過群組清單更新現有文件,則可使用 mergemergeOrUpload 動作:

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

在查詢中套用安全性篩選條件

若要根據 group_ids 存取權限調整文件,您應透過 group_ids/any(g:search.in(g, 'group_id1, group_id2,...')) 篩選條件發出搜尋查詢,其中 'group_id1, group_id2,...' 是搜尋要求簽發者的所屬群組。

group_ids 欄位包含其中一個指定識別碼的所有文件均符合此篩選條件。 如需關於使用 Azure AI 搜尋服務來搜尋文件的完整詳細資料,請參閱搜尋文件

此範例示範如何使用 POST 要求來設定查詢。

發出 HTTP POST 要求,並在要求本文中指定篩選:

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

應會取回 group_ids 包含 "group_id1" 或 "group_id2" 的文件。 換言之,您會取得要求簽發者具有讀取權限的文件。

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

下一步

本文說明根據使用者身分識別和函式 search.in() 篩選結果的模式。 您可使用此函式傳入要求使用者的主體識別碼,向每個目標文件比對關聯的主體識別碼。 處理搜尋要求時,search.in 函式會篩選出沒有任何使用者主體具備讀取權限的搜尋結果。 主體識別碼可代表安全性群組、角色等等,甚至可代表使用者的專屬身分識別。

如需更多範例、示範和影片: