Filtros de segurança para cortar os resultados da Pesquisa de IA do Azure usando o Azure Active Directory
Este artigo demonstra como usar identidades de segurança junto com filtros no Azure AI Search para cortar os resultados da pesquisa com base na associação ao grupo de usuários.
Este artigo aborda as seguintes tarefas:
- Criar grupos e usuários
- Associar o usuário ao grupo que você criou
- Armazenar em cache os novos grupos
- Indexar documentos com grupos associados
- Emitir uma solicitação de pesquisa com filtro de identificadores de grupo
Pré-requisitos
Seu índice no Azure AI Search deve ter um campo de segurança para armazenar a lista de identidades de grupo que têm acesso de leitura ao documento. Esse caso de uso pressupõe uma correspondência um-para-um entre um item protegível (como um aplicativo universitário de um indivíduo) e um campo de segurança especificando quem tem acesso a esse item (pessoal de admissão).
Você deve ter permissões de administrador de locatário (proprietário ou administrador) para criar usuários, grupos e associações.
Seu aplicativo também deve ser registrado como um aplicativo multilocatário, conforme descrito no procedimento a seguir.
Registrar seu aplicativo no Azure Active Directory
Esta etapa integra seu aplicativo ao Azure Active Directory com a finalidade de aceitar entradas de contas de usuário e grupo. Se você não for um administrador de locatários em sua organização, talvez seja necessário criar um novo locatário para executar as etapas a seguir.
No portal do Azure, localize o locatário do Azure Active Directory.
À esquerda, em Gerenciar, selecione Registros de aplicativoe, em seguida, selecione Novo registro.
Dê um nome ao registro, talvez um nome semelhante ao nome do aplicativo de pesquisa. Consulte este artigo para obter informações sobre outras propriedades opcionais.
Selecione Registro.
Depois que o registro do aplicativo for criado, copie a ID de Aplicativo (Cliente). Você precisará fornecer essa cadeia de caracteres ao seu aplicativo.
Se você estiver percorrendo o DotNetHowToSecurityTrimming, cole este valor no arquivo app.config.
Copie o ID do Diretório (locatário).
À esquerda, selecione permissões de API e selecione Adicionar uma permissão.
Selecione Microsoft Graph e selecione Permissões delegadas.
Pesquise e adicione as seguintes permissões delegadas:
- Directory.ReadWrite.All
- Group.ReadWrite.All
- User.LerEscrever.Tudo
O Microsoft Graph fornece uma API que permite acesso programático ao Azure Active Directory por meio de uma API REST. O exemplo de código para este passo a passo usa as permissões para chamar a API do Microsoft Graph para criar grupos, usuários e associações. As APIs também são usadas para armazenar em cache identificadores de grupo para filtragem mais rápida.
Selecione para conceder consentimento de administrador ao locatário para concluir o processo de consentimento.
Criar usuários e grupos
Se você estiver adicionando pesquisa a um aplicativo estabelecido, poderá ter identificadores de usuário e grupo existentes no Azure Active Directory. Nesse caso, você pode ignorar as próximas três etapas.
No entanto, se você não tiver usuários existentes, poderá usar as APIs do Microsoft Graph para criar os principais de segurança. Os snippets de código a seguir demonstram como gerar identificadores, que se tornam valores de dados para o campo de segurança no índice do Azure AI Search. Em nosso hipotético aplicativo de admissão universitária, este seria o identificador de segurança para a equipe de admissão.
A associação de usuários e grupos pode ser muito fluida, especialmente em grandes organizações. O código que cria identidades de usuário e de grupo deve ser executado com frequência suficiente para obter alterações na associação da organização. Da mesma forma, o índice do Azure AI Search requer um agendamento de atualização semelhante para refletir o status atual de usuários e recursos permitidos.
Etapa 1: criar grupo
private static Dictionary<Group, List<User>> CreateGroupsWithUsers(string tenant)
{
Group group = new Group()
{
DisplayName = "My First Prog Group",
SecurityEnabled = true,
MailEnabled = false,
MailNickname = "group1"
};
Etapa 2: Criar Usuário
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
};
Etapa 3: Associar usuário e grupo
List<User> users = new List<User>() { user1, user2 };
Dictionary<Group, List<User>> groups = new Dictionary<Group, List<User>>() { { group, users } };
Etapa 4: Armazenar em cache os identificadores de grupos
Opcionalmente, para reduzir a latência de rede, você pode armazenar em cache as associações de grupo de usuários para que, quando uma solicitação de pesquisa seja emitida, os grupos sejam retornados do cache, salvando uma viagem de ida e volta. Você pode usar a API do Lote para enviar uma única solicitação HTTP com vários usuários e construir o cache.
O Microsoft Graph foi projetado para lidar com um alto volume de solicitações. Se ocorrer um número avassalador de solicitações, o Microsoft Graph falhará na solicitação com o código de status HTTP 429. Para obter mais informações, consulte de limitação do Microsoft Graph.
Indexar documento com seus grupos permitidos
As operações de consulta no Azure AI Search são executadas em um índice do Azure AI Search. Nesta etapa, uma operação de indexação importa dados pesquisáveis para um índice, incluindo os identificadores usados como filtros de segurança.
O Azure AI Search não autentica identidades de usuário nem fornece lógica para estabelecer qual conteúdo um usuário tem permissão para exibir. O caso de uso do corte de segurança pressupõe que você forneça a associação entre um documento confidencial e o identificador de grupo que tem acesso a esse documento, importado intacto em um índice de pesquisa.
No exemplo hipotético, o corpo da solicitação PUT em um índice do Azure AI Search incluiria a redação ou o histórico escolar de um candidato, juntamente com o identificador de um grupo que tenha permissão para visualizar esse conteúdo.
No exemplo genérico usado no exemplo de código para este passo a passo, a ação de índice pode ser a seguinte:
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);
Emitir uma solicitação de pesquisa
Para fins de ajuste de segurança, os valores do seu campo de segurança no índice são valores estáticos utilizados para incluir ou excluir documentos nos resultados de pesquisa. Por exemplo, se o identificador de grupo para Admissões for "A11B22C33D44-E55F66G77-H88I99JKK", quaisquer documentos em um índice do Azure AI Search que tenham esse identificador no campo de segurança serão incluídos (ou excluídos) nos resultados da pesquisa enviados de volta ao chamador.
Para filtrar documentos retornados nos resultados da pesquisa com base em grupos do usuário que está emitindo a solicitação, examine as etapas a seguir.
Etapa 1: recuperar identificadores de grupo do usuário
Se os grupos do usuário ainda não estiverem armazenados em cache ou se o cache tiver expirado, faça a solicitação de grupos .
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);
}
Etapa 2: Compor a solicitação de pesquisa
Supondo que você tenha a filiação aos grupos do usuário, poderá emitir a solicitação de pesquisa com os valores de filtro adequados.
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));
}
Etapa 3: Manipular os resultados
A resposta inclui uma lista filtrada de documentos, que consiste naqueles que o usuário tem permissão para exibir. Dependendo de como você constrói a página de resultados da pesquisa, talvez você queira incluir indicações visuais para refletir o conjunto de resultados filtrado.
Principais pontos
Neste passo a passo, você aprendeu um padrão para usar entradas de usuário para filtrar documentos nos resultados da Pesquisa de IA do Azure, cortando os resultados de documentos que não correspondem ao filtro fornecido na solicitação.