用于使用 Active Directory 标识修剪 Azure 认知搜索结果的安全筛选器Security filters for trimming Azure Cognitive Search results using Active Directory identities

本文演示如何结合使用 Azure Active Directory (AAD) 安全标识和 Azure 认知搜索中的筛选器基于用户组成员身份来修剪搜索结果。This article demonstrates how to use Azure Active Directory (AAD) security identities together with filters in Azure Cognitive Search to trim search results based on user group membership.

本文涵盖以下任务:This article covers the following tasks:

  • 创建 AAD 组和用户Create AAD groups and users
  • 将用户与创建的组相关联Associate the user with the group you have created
  • 缓存新组Cache the new groups
  • 使用关联的组编制文档索引Index documents with associated groups
  • 使用组标识符筛选器发出搜索请求Issue a search request with group identifiers filter

备注

本文中的示例代码片段是用 C# 语言编写的。Sample code snippets in this article are written in C#. 可以 在 GitHub 上找到完整的源代码。You can find the full source code on GitHub.

先决条件Prerequisites

Azure 认知搜索中的索引必须有一个安全字段用于存储对文档拥有读取访问权限的组标识列表。Your index in Azure Cognitive Search must have a security field to store the list of group identities having read access to the document. 此用例假设某个安全对象项(例如个人的大学申请)与指定谁有权访问该项(招生人员)的安全字段之间存在一对一的对应关系。This use case assumes a one-to-one correspondence between a securable item (such as an individual's college application) and a security field specifying who has access to that item (admissions personnel).

在本演练中,必须拥有 AAD 管理员权限才能在 AAD 中创建用户、组和关联。You must have AAD administrator permissions, required in this walkthrough for creating users, groups, and associations in AAD.

此外,必须根据以下过程所述,将应用程序注册到 AAD。Your application must also be registered with AAD, as described in the following procedure.

将应用程序注册到 AADRegister your application with AAD

此步骤将应用程序与 AAD 集成,以接受用户和组帐户的登录。This step integrates your application with AAD for the purpose of accepting sign-ins of user and group accounts. 如果你不是组织中的 AAD 管理员,可能需要创建新租户才能执行以下步骤。If you are not an AAD admin in your organization, you might need to create a new tenant to perform the following steps.

  1. 转到应用程序注册门户 > 选择“聚合应用” > “添加应用”。 Go to the Application Registration Portal > Converged app > Add an app.

  2. 输入应用程序的名称,单击“创建”。Enter a name for your application, then click Create.

  3. 在“我的应用程序”页中选择新注册的应用程序。Select your newly registered application in the My Applications page.

  4. 在应用程序注册页上 > 选择“平台” > “添加平台”>“Web API”。 On the application registration page > Platforms > Add Platform, choose Web API.

  5. 仍在应用程序注册页上,转到“Microsoft Graph 权限” > “添加”。 Still on the application registration page, go to > Microsoft Graph Permissions > Add.

  6. 在“选择权限”中添加以下委托权限,单击“确定”:In Select Permissions, add the following delegated permissions and then click OK:

    • Directory.ReadWrite.AllDirectory.ReadWrite.All
    • Group.ReadWrite.AllGroup.ReadWrite.All
    • User.ReadWrite.AllUser.ReadWrite.All

可以使用 Microsoft Graph 提供的某个 API 通过 REST API 以编程方式访问 AAD。Microsoft Graph provides an API that allows programmatic access to AAD through a REST API. 本演练的代码示例使用调用 Microsoft 图形 API 的权限来创建组、用户和关联。The code sample for this walkthrough uses the permissions to call the Microsoft Graph API for creating groups, users, and associations. 还可以使用 API 缓存组标识符以提高筛选速度。The APIs are also used to cache group identifiers for faster filtering.

创建用户和组Create users and groups

如果正在向建立的应用程序添加搜索,AAD 中可能已包含现有的用户和组标识符。If you are adding search to an established application, you might have existing user and group identifiers in AAD. 在这种情况下,可以跳过接下来的三个步骤。In this case, you can skip the next three steps.

但是,如果没有现有用户,可以使用 Microsoft 图形 API 创建安全主体。However, if you don't have existing users, you can use Microsoft Graph APIs to create the security principals. 以下代码片段演示如何生成标识符,这些标识符将成为 Azure 认知搜索索引中安全字段的数据值。The following code snippets demonstrate how to generate identifiers, which become data values for the security field in your Azure Cognitive Search index. 在虚构的大学招生应用程序中,这些标识符将是招生工作人员的安全标识符。In our hypothetical college admissions application, this would be the security identifiers for admissions staff.

用户和组的成员身份可能很不稳定,尤其是在大型组织中。User and group membership might be very fluid, especially in large organizations. 生成用户和组标识的代码应该以足够高的频率运行,以拾取组织成员身份的更改。Code that builds user and group identities should run often enough to pick up changes in organization membership. 同样,Azure 认知搜索索引需有类似的更新计划,以反映受允许用户和资源的当前状态。Likewise, your Azure Cognitive Search index requires a similar update schedule to reflect the current status of permitted users and resources.

步骤 1:创建 AAD 组Step 1: Create AAD Group

// Instantiate graph client 
GraphServiceClient graph = new GraphServiceClient(new DelegateAuthenticationProvider(...));
Group group = new Group()
{
    DisplayName = "My First Prog Group",
    SecurityEnabled = true,
    MailEnabled = false,
    MailNickname = "group1"
}; 
Group newGroup = await graph.Groups.Request().AddAsync(group);

步骤 2:创建 AAD 用户Step 2: Create AAD User

User user = new User()
{
    GivenName = "First User",
    Surname = "User1",
    MailNickname = "User1",
    DisplayName = "First User",
    UserPrincipalName = "User1@FirstUser.com",
    PasswordProfile = new PasswordProfile() { Password = "********" },
    AccountEnabled = true
};
User newUser = await graph.Users.Request().AddAsync(user);

步骤 3:将用户和组相关联Step 3: Associate user and group

await graph.Groups[newGroup.Id].Members.References.Request().AddAsync(newUser);

步骤 4:缓存组标识符Step 4: Cache the groups identifiers

(可选)为了降低网络延迟,可以缓存用户与组之间的关联,以便在发出搜索请求后,可以从缓存返回组,免除与 AAD 之间的一次往返。Optionally, to reduce network latency, you can cache the user-group associations so that when a search request is issued, groups are returned from the cache, saving a roundtrip to AAD. 可以使用 AAD Batch API 发送包含多个用户的单个 Http 请求并生成缓存。You can use AAD Batch API to send a single Http request with multiple users and build the cache.

Microsoft Graph 能够处理大量的请求。Microsoft Graph is designed to handle a high volume of requests. 如果发出无以数计的请求,Microsoft Graph 将会失败并返回 HTTP 状态代码 429。If an overwhelming number of requests occur, Microsoft Graph fails the request with HTTP status code 429. 有关详细信息,请参阅 Microsoft Graph 限制For more information, see Microsoft Graph throttling.

使用受允许的组编制文档索引Index document with their permitted groups

Azure 认知搜索中的查询操作是基于 Azure 认知搜索索引执行的。Query operations in Azure Cognitive Search are executed over an Azure Cognitive Search index. 在此步骤中,索引操作会将可搜索的数据(包括用作安全筛选器的标识符)导入索引。In this step, an indexing operation imports searchable data into an index, including the identifiers used as security filters.

Azure 认知搜索不会验证用户的身份,也不提供逻辑来确定用户有权查看哪些内容。Azure Cognitive Search does not authenticate user identities, or provide logic for establishing which content a user has permission to view. 安全修整的用例假设在某个敏感文档与有权访问该文档的组标识符之间提供了关联,并将这种关联按原样导入了搜索索引。The use case for security trimming assumes that you provide the association between a sensitive document and the group identifier having access to that document, imported intact into a search index.

在虚构的示例中,Azure 认知搜索索引中 PUT 请求的正文应包含申请者的大学申请短文或成绩报告单,以及有权查看该内容的组标识符。In the hypothetical example, the body of the PUT request on an Azure Cognitive Search index would include an applicant's college essay or transcript along with the group identifier having permission to view that content.

在本演练的代码示例使用的常规示例中,索引操作可能如下所示:In the generic example used in the code sample for this walkthrough, the index action might look as follows:

var actions = new IndexAction<SecuredFiles>[]
              {
                  IndexAction.Upload(
                  new SecuredFiles()
                  {
                      FileId = "1",
                      Name = "secured_file_a",
                      GroupIds = new[] { groups[0] }
                  }),
              ...
             };

var batch = IndexBatch.New(actions);

_indexClient.Documents.Index(batch);  

发出搜索请求Issue a search request

为了进行安全修整,索引的安全字段中的值是静态值,用于在搜索结果中包含或排除文档。For security trimming purposes, the values in your security field in the index are static values used for including or excluding documents in search results. 例如,如果招生人员的组标识符为“A11B22C33D44-E55F66G77-H88I99JKK”,则会在发回给请求者的搜索结果中,包含(或排除)安全字段包含该标识符的 Azure 认知搜索索引中的所有文档。For example, if the group identifier for Admissions is "A11B22C33D44-E55F66G77-H88I99JKK", any documents in an Azure Cognitive Search index having that identifier in the security filed are included (or excluded) in the search results sent back to the requestor.

若要基于发出请求的用户组筛选搜索结果中返回的文档,请查看以下步骤。To filter documents returned in search results based on groups of the user issuing the request, review the following steps.

步骤 1:检索用户的组标识符Step 1: Retrieve user's group identifiers

如果用户的组尚未缓存或缓存已过期,请发出请求If the user's groups were not already cached, or the cache has expired, issue the groups request

private static void RefreshCacheIfRequired(string user)
{
    if (!_groupsCache.ContainsKey(user))
    {
        var groups = GetGroupIdsForUser(user).Result;
        _groupsCache[user] = groups;
    }
}

private static async Task<List<string>> GetGroupIdsForUser(string userPrincipalName)
{
    List<string> groups = new List<string>();
    var allUserGroupsRequest = graph.Users[userPrincipalName].GetMemberGroups(true).Request();

    while (allUserGroupsRequest != null) 
    {
        IDirectoryObjectGetMemberGroupsRequestBuilder allUserGroups = await allUserGroupsRequest.PostAsync();
        groups = allUserGroups.ToList();
        allUserGroupsRequest = allUserGroups.NextPageRequest;
    }
    return groups;
}

步骤 2:撰写搜索请求Step 2: Compose the search request

假设你拥有用户的组成员身份,则可以使用相应的筛选器值发出搜索请求。Assuming you have the user's groups membership, you can issue the search request with the appropriate filter values.

string filter = String.Format("groupIds/any(p:search.in(p, '{0}'))", string.Join(",", groups.Select(g => g.ToString())));
SearchParameters parameters = new SearchParameters()
             {
                 Filter = filter,
                 Select = new[] { "application essays" }
             };

DocumentSearchResult<SecuredFiles> results = _indexClient.Documents.Search<SecuredFiles>("*", parameters);

步骤 3:处理结果Step 3: Handle the results

响应包含文档的筛选列表,该列表由用户有权查看的文档构成。The response includes a filtered list of documents, consisting of those that the user has permission to view. 根据搜索结果页的构造方式,可能需要包含视觉线索来反映筛选的结果集。Depending on how you construct the search results page, you might want to include visual cues to reflect the filtered result set.

结论Conclusion

本演练已介绍如何使用 AAD 登录名筛选 Azure 认知搜索结果中的文档,以及修剪与请求中提供的筛选器不匹配的文档结果。In this walkthrough, you learned techniques for using AAD sign-ins to filter documents in Azure Cognitive Search results, trimming the results of documents that do not match the filter provided on the request.

另请参阅See also