共用方式為


使用 MAzure Active Directory 修剪 Azure AI 搜尋結果的安全性篩選

本文示範如何使用安全性身分識別與 Azure AI 搜尋中的篩選條件,根據使用者群組成員資格來修剪搜尋結果。

本文涵蓋下列工作:

  • 建立群組和使用者
  • 將使用者與您建立的群組相關聯
  • 快取新的群組
  • 使用相關聯的群組索引文件
  • 使用群組識別碼篩選條件發出搜尋要求

必要條件

您在 Azure AI 搜尋服務中的索引必須有安全性欄位,才能儲存具有文件讀取權限的群組身分識別清單。 此使用案例會假設安全性實體項目 (例如個人的大學應用程式) 與指定可存取該項目之人員 (許可人員) 的安全性欄位之間的一對一對應。

您必須擁有租用戶系統管理員許可權(擁有者或系統管理員),才能建立使用者、群組和關聯。

您的應用程式也必須註冊為多租用戶應用程式,如下列程式所述。

向 Azure Active Directory 註冊應用程式

此步驟會整合您的應用程式與 Azure Active Directory,以便接受使用者和組帳戶的登入。 如果您在貴組織中不是租用戶管理員,可能需要建立新的租用戶才能執行下列步驟。

  1. Azure 入口網站 中,尋找 Azure Active Directory 租使用者。

  2. 在左側的 [管理] 下方,選取 [應用程式註冊],然後選取 [新增註冊]

  3. 為註冊命名,或許可採用與搜尋應用程式名稱類似的名稱。 如需其他選擇性屬性的相關資訊,請參閱這篇文章

  4. 選取註冊

  5. 建立應用程式註冊之後,複製應用程式 (用戶端) ID。 您必須將此字串提供給您的應用程式。

    如果您要逐步執行 DotNetHowToSecurityTrimming,請將此值貼到 app.config 檔案中。

  6. 複製目錄 (租用戶) 識別碼。

  7. 在左側選取 [API 權限],然後選取 [新增權限]

  8. 選取 [Microsoft Graph],然後選取 [委派權限]

  9. 搜尋並新增下列委派權限:

    • Directory.ReadWrite.All
    • Group.ReadWrite.All
    • User.ReadWrite.All

    Microsoft Graph 提供 API,允許透過 REST API 以程式設計方式存取 Azure Active Directory。 本逐步解說的程式碼範例會使用權限來呼叫 Microsoft Graph API,以建立群組、使用者和關聯。 API 也可用來快取群組識別碼以加速篩選。

  10. 選取 [Grant admin consent for tenant] \(授與租用戶的管理員同意\),以完成同意流程。

建立使用者與群組

如果您要將搜尋新增至已建立的應用程式,則 Azure Active Directory 中可能有現有的使用者和群組識別碼。 在此情況下,您可以跳過接下來的三個步驟。

不過,如果您沒有現有的使用者,可以使用 Microsoft Graph API 來建立安全性主體。 下列程式碼片段會示範如何產生識別碼,從而成為 Azure AI 搜尋服務索引中安全性欄位的資料值。 在我們假設的大學許可應用程式中,這會是許可人員適用的安全性識別碼。

使用者和群組成員資格可能很流暢,尤其是在大型組織中。 建置使用者和群組身分識別的程式碼應該經常執行,才能挑選組織成員資格中的變更。 同樣地,您的 Azure AI 搜尋服務索引需要類似的更新排程,才能反映許可使用者和資源的目前狀態。

步驟 1:建立群組

private static Dictionary<Group, List<User>> CreateGroupsWithUsers(string tenant)
{
    Group group = new Group()
    {
        DisplayName = "My First Prog Group",
        SecurityEnabled = true,
        MailEnabled = false,
        MailNickname = "group1"
    };

步驟 2:建立使用者

User user1 = new User()
{
    GivenName = "First User",
    Surname = "User1",
    MailNickname = "User1",
    DisplayName = "First User",
    UserPrincipalName = String.Format("user1@{0}", tenant),
    PasswordProfile = new PasswordProfile() { Password = "********" },
    AccountEnabled = true
};

步驟 3:建立使用者和群組的關聯

List<User> users = new List<User>() { user1, user2 };
Dictionary<Group, List<User>> groups = new Dictionary<Group, List<User>>() { { group, users } };

步驟 4:快取群組識別碼

或者,若要減少網路等待時間,您可以快取使用者群組關聯,以便在發出搜尋要求時,從快取傳回群組,以節省往返。 您可以使用 Batch API 來傳送具有多個使用者的單一 Http 要求,並建置快取。

Microsoft Graph 依設計可處理大量的要求。 如果發生大量的要求,Microsoft Graph 會無法執行要求,並顯示 HTTP 狀態碼 429。 如需詳細資訊,請參閱 Microsoft Graph 節流

使用其允許的群組索引文件

Azure AI 搜尋服務中的查詢作業會透過 Azure AI 搜尋服務索引執行。 在此步驟中,索引作業會將可搜尋資料匯入索引中,包含用來作為安全性篩選器的識別碼。

Azure AI 搜尋服務不會驗證使用者身分識別,或提供用於建立使用者有權檢視內容的邏輯。 安全性調整的使用案例會假設您在機密文件與擁有該文件存取權的群組識別碼之間提供關聯,完整匯入搜尋索引。

在假設性範例中,Azure AI 搜尋服務索引上的 PUT 要求主體會包含申請者的大學論文或成績單,以及擁有權限可檢視該內容的群組識別碼。

在本逐步解說用於程式碼範例的一般範例中,索引動作看起來可能會像這樣:

private static void IndexDocuments(string indexName, List<string> groups)
{
    IndexDocumentsBatch<SecuredFiles> batch = IndexDocumentsBatch.Create(
        IndexDocumentsAction.Upload(
            new SecuredFiles()
            {
                FileId = "1",
                Name = "secured_file_a",
                GroupIds = new[] { groups[0] }
            }),
              ...
            };

IndexDocumentsResult result = searchClient.IndexDocuments(batch);

發出搜尋要求

基於安全性調整的目的,您在索引之安全性欄位中的值會是靜態值,用來包含或排除搜尋結果中的文件。 例如,如果許可的群組識別碼是 "A11B22C33D44-E55F66G77-H88I99JKK",就會在傳回給呼叫者的搜尋結果中,包含 (或排除) 安全性欄位中具有該識別碼的 Azure AI 搜尋服務索引中的任何文件。

若要篩選以發出要求的使用者群組作為基礎的搜尋結果中傳回之文件,請請檢閱下列的步驟。

步驟 1:擷取使用者的群組識別碼

如果使用者的群組尚未快取或是快取已過期,請發出群組要求。

private static async void RefreshCache(IEnumerable<User> users)
{
    HttpClient client = new HttpClient();
    var userGroups = await _microsoftGraphHelper.GetGroupsForUsers(client, users);
    _groupsCache = new ConcurrentDictionary<string, List<string>>(userGroups);
}

步驟 2:撰寫搜尋要求

假設您具有使用者的群組成員資格,就可以使用適當的篩選器值來發出搜尋要求。

private static void SearchQueryWithFilter(string user)
{
    // Using the filter below, the search result will contain all documents that their GroupIds field   
    // contain any one of the Ids in the groups list
    string filter = String.Format("groupIds/any(p:search.in(p, '{0}'))", string.Join(",", String.Join(",", _groupsCache[user])));
    SearchOptions searchOptions =
        new SearchOptions()
        {
            Filter = filter
        };
    searchOptions.Select.Add("name");

    SearchResults<SecuredFiles> results = searchClient.Search<SecuredFiles>("*", searchOptions);

    Console.WriteLine("Results for groups '{0}' : {1}", _groupsCache[user], results.GetResults().Select(r => r.Document.Name));
}

步驟 3:處理結果

回應包括文件的篩選清單,包含使用者有權限檢視的項目。 根據您建構搜尋結果頁面的方式,建議您包括視覺提示,以反映篩選的結果集。

重要心得

在本逐步解說中,您已瞭解使用使用者登入在 Azure AI 搜尋服務結果中篩選檔的模式,並修剪不符合要求上所提供篩選條件的文件結果。