Partager via


Filtres de sécurité pour découper les résultats de recherche Azure AI à l’aide de MAzure Active Directory

Cet article montre comment utiliser des identités de sécurité avec des filtres dans Recherche IA Azure pour réduire les résultats de la recherche en fonction de l’appartenance au groupe d’utilisateurs.

Cet article décrit les tâches suivantes :

  • Créer des groupes et des utilisateurs
  • Associer l’utilisateur au groupe que vous avez créé
  • Mettre en cache les nouveaux groupes
  • Indexer les documents avec les groupes associés
  • Émettre une demande de recherche avec un filtre d’identificateurs de groupe

Prérequis

Votre index dans la recherche Azure AI doit avoir un champ de sécurité pour stocker la liste des identités de groupe disposant d’un accès en lecture pour le document. Ce cas d’usage implique une correspondance exacte entre un élément sécurisable (par exemple l’application d’un établissement scolaire) et un champ de sécurité spécifiant qui a accès à cet élément (personnel en charge des admissions).

Vous devez disposer d’autorisations d’administrateur client (propriétaire ou administrateur) pour créer des utilisateurs, des groupes et des associations.

Votre application doit également être inscrite auprès d’une application multilocataire, comme décrit dans la procédure suivante.

Inscrire votre application auprès d’Azure Active Directory

Cette étape intègre votre application à Azure Active Directory pour accepter les connexions des comptes d’utilisateur et de groupe. Si vous n’êtes pas administrateur de locataire dans votre organisation, vous devrez peut-être créer un nouveau locataire pour effectuer les étapes suivantes.

  1. Dans Portail Azure, recherchez le locataire Azure Active Directory.

  2. Sur la gauche, sous Gérer, sélectionnez Inscriptions d’applications, puis sélectionnez Nouvelle inscription.

  3. Donnez un nom à l’inscription, peut-être un nom similaire au nom de l’application de recherche. Pour plus d’informations sur les autres propriétés optionnelles, reportez-vous à cet article.

  4. Sélectionnez Inscrire.

  5. Une fois l’inscription de l’application créée, copiez l’ID d’application (client). Vous devrez fournir cette chaîne à votre application.

    Si vous parcourez DotNetHowToSecurityTrimming, collez cette valeur dans le fichier app.config. app.config.

  6. Copiez l’ID d’annuaire (locataire).

  7. Sur la gauche, sélectionnez Autorisations d’API, puis Ajouter une autorisation.

  8. Sélectionnez Microsoft Graph, puis Autorisations déléguées.

  9. Recherchez et ajoutez les autorisations déléguées suivantes :

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

    Microsoft Graph fournit une API qui autorise l’accès par programmation à Azure Active Directory via une API REST. L’exemple de code pour cette procédure utilise les autorisations pour appeler l’API Microsoft Graph pour la création de groupes, d’utilisateurs et d’associations. Les API sont également utilisées pour mettre en cache les identificateurs de groupe afin d’accélérer le filtrage.

  10. Sélectionnez Accorder le consentement administrateur pour le locataire pour terminer le processus de consentement.

Créer des utilisateurs et des groupes

Si vous ajoutez une recherche à une application établie, vous pouvez avoir des identificateurs d’utilisateur et de groupe existants dans Azure Active Directory. Dans ce cas, vous pouvez ignorer les trois étapes suivantes.

Toutefois, si vous n’avez pas d’utilisateurs existants, vous pouvez utiliser les API Microsoft Graph pour créer des entités de sécurité. Les extraits de code suivants montrent comment générer des identificateurs qui deviennent des valeurs de données pour le champ de sécurité dans votre index de recherche Azure AI. Dans l’exemple de notre application d’admission scolaire, il s’agirait des identificateurs de sécurité pour le personnel en charge des admissions.

La gestion des groupes et des utilisateurs peut s’avérer très fluide, en particulier dans les grandes organisations. Le code qui génère les identités d’utilisateur et de groupe doit s’exécuter assez souvent pour tenir compte des modifications apportées aux groupes de l’organisation. De même, votre index de recherche Azure AI requiert une planification de mise à jour similaire pour refléter l’état actuel des utilisateurs et des ressources autorisés.

Étape 1 : Créer une offre

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

Étape 2 : Créer un utilisateur

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

Étape 3 : Associer les utilisateurs et les groupes

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

Étape 4 : Mettre en cache les identificateurs de groupe

Si vous le souhaitez, pour réduire la latence du réseau, vous pouvez mettre en cache les associations de groupes d’utilisateurs afin que lorsqu’une demande de recherche soit émise, les groupes sont retournés à partir du cache, en enregistrant un aller-retour. Vous pouvez utiliser l’API Batch pour envoyer une requête Http unique avec plusieurs utilisateurs et générer le cache.

Microsoft Graph est conçu pour gérer un volume élevé de demandes. Si un trop grand nombre de demandes sont émises, Microsoft Graph génère une erreur avec le code d’état HTTP 429. Pour plus d’informations, consultez le document Limitation dans Microsoft Graph.

Indexer les documents avec leurs groupes autorisés

Les opérations de requête dans la recherche Azure AI sont exécutées via un index de recherche Azure AI. Dans cette étape, une opération d’indexation importe les données interrogeables sous forme d’index, y compris les identificateurs utilisés comme filtres de sécurité.

La recherche Azure AI n’authentifie pas les identités des utilisateurs et ne fournit aucune logique pour définir le contenu qu’un utilisateur est autorisé à consulter. Le cas d’usage pour le filtrage de sécurité implique que vous fournissiez l’association entre un document sensible et l’identificateur de groupe ayant accès à ce document importé sans modification dans un index de recherche.

Dans notre exemple hypothétique, le corps de la requête PUT sur un index de recherche Azure AI inclurait une épreuve ou une transcription d’un candidat, ainsi que l’identificateur de groupe ayant l’autorisation d’afficher ce contenu.

Dans l’exemple générique utilisé dans l’exemple de code pour cette procédure, l’action d’indexation peut se présenter comme suit :

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);

Émettre une demande de recherche

Pour des raisons de filtrage de sécurité, les valeurs du champ de sécurité dans l’index sont des valeurs statiques utilisées pour inclure ou exclure des documents dans les résultats de la recherche. Par exemple, si l’identificateur de groupe pour les admissions est « A11B22C33D44-E55F66G77-H88I99JKK », tous les documents dans un index de recherche Azure AI ayant cet identificateur dans le champ de sécurité sont inclus (ou exclus) dans les résultats de la recherche renvoyés à l’appelant.

Pour filtrer les documents renvoyés dans les résultats de la recherche en fonction des groupes de l’utilisateur qui émet la demande, procédez comme suit.

Étape 1 : Récupérer les identificateurs de groupe de l’utilisateur

Si les groupes de l’utilisateur n’ont pas encore été mis en cache, ou si le cache a expiré, exécutez la requête groups.

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);
}

Étape 2 : Composer la demande de recherche

En supposant que vous connaissez les groupes de l’utilisateur, vous pouvez émettre la demande de recherche avec les valeurs de filtre appropriées.

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));
}

Étape 3 : Gérer les résultats

La réponse inclut une liste répertoriant uniquement les documents que l’utilisateur est autorisé à afficher. Selon la façon dont vous construisez la page de résultats, vous pouvez inclure des repères visuels pour matérialiser le jeu de résultats obtenu.

Éléments importants à retenir

Dans cette procédure pas à pas, vous avez appris un modèle d’utilisation des connexions utilisateur pour filtrer les documents dans les résultats de Recherche IA Azure, en réduisant les résultats des documents qui ne correspondent pas au filtre fourni sur la demande.