Sécurité

PowerPortalsPro propose un modèle de sécurité flexible piloté par le code qui vous permet de contrôler l’accès à la fois au niveau de la table et du niveau des enregistrements. La sécurité est mise en œuvre en créant des classes de gestionnaire de permissions et en les enregistrant dans le conteneur d’injection de dépendances.

Aperçu

Il existe deux interfaces que vous pouvez implémenter selon le niveau de contrôle dont vous avez besoin :

Conseil

Si vous n’avez besoin que de vérifications au niveau de la table (par exemple « les utilisateurs authentifiés peuvent lire ce tableau »), utilisez ITablePermissionHandler. Si vous avez besoin de logique au niveau des enregistrements (par exemple « les utilisateurs ne peuvent supprimer que les enregistrements qu’ils possèdent »), utilisez ITableRecordPermissionHandler.

Bonne pratique — filtrer à la source

Les gestionnaires d’autorisations imposent l’accès, mais ils ne remplacent pas le filtrage. Les gestionnaires au niveau des enregistrements s’exécutent après qu’une page d’enregistrements a été récupérée depuis Dataverse, donc compter sur eux pour masquer les lignes déforme la pagination de la grille (une page de 50 peut en montrer moins) et le nombre total, et gaspille des requêtes en récupérant des lignes qui sont ensuite rejetées. Chaque fois que des données doivent être attribuées à l’utilisateur actuel, filtrez au niveau de la requête — avec une IFetchXmlQueryFilterInterceptor vue (voir ci-dessous) ou personnalisée qui tient compte de l’utilisateur actuel — afin que Dataverse ne rende que les lignes que l’utilisateur doit voir et que la page grille correctement. Gardez les responsables des permissions comme garantie d’application.

Dataverse-Native Security (Aperçu)

Le modèle de sécurité recommandé pour la suite permet à Dataverse lui-même d’assurer la sécurité pour les utilisateurs de votre portail, basé sur la fonctionnalité de sécurité unifiée Dataverse de Power Pages. Au lieu d’écrire des gestionnaires de permissions en code, vous gérez l’accès avec des rôles de sécurité standards Dataverse — les mêmes rôles, privilèges et outils administratifs utilisés pour les utilisateurs internes. Le modèle est actuellement en version preview — à la fois la fonctionnalité de Microsoft et le support de Power Portals Pro — et Power Portals Pro suivra le calendrier de sortie de Microsoft jusqu’à la disponibilité générale.

Une fois activé, PowerPortalsPro fournit automatiquement un système géré (C2) systemuser pour chaque contact portail — à l’enregistrement pour les nouveaux contacts, et paresseusement à la connexion pour les existants — ainsi que l’enregistrement powerpagesusermapping qui relie le contact, l’utilisateur système et votre site Power Pages. Chaque appel Dataverse pour la session se fait alors passer pour cet utilisateur système, de sorte que les rôles de sécurité que Power Pages synchronise à partir de vos rôles web et vos permissions de table régissent exactement ce que l’utilisateur peut voir et faire. La session comporte un PortalUserType de ContactStubUser afin que votre interface puisse toujours distinguer ces utilisateurs provisionnés des utilisateurs internes réels.

Note

Pour utiliser ce modèle de sécurité, vous devez créer un site web Power Pages dans votre environnement Dataverse — c’est ce qui installe les composants du cadre Microsoft et permet d’activer la fonctionnalité de sécurité unifiée. Vous n’avez pas besoin d’un forfait Power Pages payant, et vous pouvez supprimer le site web lui-même immédiatement après avoir installé et activé la fonctionnalité. L’enregistrement de site Power Pages (powerpagesite) référencé par PowerPagesSiteId doit exister dans l’environnement, car les mappages utilisateur et la synchronisation sécurité-rôle se résolvent contre celui-ci.

Activation de la sécurité Dataverse Native

Activez le modèle dans SecurityOptions le fichier de Program.csvotre serveur , en fournissant l’identifiant de votre site Power Pages :

La configuration est validée au démarrage de l’application : lorsqu’elle ProvisionSystemUsers est activée, PowerPagesSiteId elle doit être définie et doit se résoudre à un enregistrement existant powerpagesite , sinon l’application ne démarre pas avec des instructions.

Accordez l’accès exactement comme le fait Power Pages : configurez les rôles web et les permissions de table dans l’application Power Pages Management, et attribuez des rôles web aux contacts (via l’application Management ou de manière programmatique). La plateforme synchronise ces rôles en rôles de sécurité générés automatiquement (nommés PowerPages_*) et les attribue automatiquement au fur et à mesure que l’adhésion au rôle web change — comme la configuration est entièrement dans Power Pages, votre portail peut se déplacer vers ou depuis un site Power Pages réel sans aucune friction. Notez que les changements de rôle et de privilège peuvent prendre de quelques secondes à quelques minutes pour se propager dans les caches de Dataverse avant d’entrer en vigueur.

Suivez le guide de configuration étape par étape

Commencer

1. Créer un gestionnaire de permissions

Créez une classe qui implémente ITablePermissionHandler ou ITableRecordPermissionHandler. Définissez la Table propriété au nom logique de la table Dataverse à laquelle le gestionnaire s’applique, et implémentez chaque méthode d’autorisation.

Voici un exemple simple qui accorde un accès complet à tous les utilisateurs pour une table spécifique :

2. Enregistrer dans l’injection de dépendance

Enregistrez votre gestionnaire dans le conteneur DI du Program.cs fichier de votre projet (ou une méthode d’extension de collection de services) :

Puisque les gestionnaires sont résolus depuis le conteneur DI, vous pouvez injecter tous les services nécessaires (comme un contexte de base de données ou un service utilisateur) via l’injection de constructeurs.

Sécurité au niveau des enregistrements

Pour les scénarios où l’accès dépend de l’enregistrement spécifique sur lequel on travaille, implémentez ITableRecordPermissionHandler. Cette interface s’étend ITablePermissionHandler avec les surcharges qui reçoivent le TableRecord.

L’exemple suivant permet à tous les utilisateurs de lire les enregistrements globalement, mais limite les opérations d’écriture aux enregistrements appartenant à l’utilisateur actuel :

Note

La CanUpdateAsync surcharge au niveau de l’enregistrement fournit à la fois à l’enregistrement les mises à jour proposées (recordWithUpdates) et à l’enregistrement dans son état actuellement persisté (currentRecord), ce qui vous permet de comparer des valeurs ou de valider des modifications spécifiques du champ.

Colonnes requises

La RequiredColumns propriété spécifie quelles colonnes doivent être récupérées pour que le gestionnaire puisse évaluer les permissions au niveau des enregistrements. Le framework ajoute automatiquement ces colonnes aux requêtes FetchXML lorsqu’elles ne sont pas déjà incluses, garantissant que le gestionnaire dispose toujours des données dont il a besoin — même si la vue ou la requête n’inclut pas ces colonnes.

L’exemple suivant utilise la ppp_owningportaluserid colonne de recherche pour restreindre l’accès aux enregistrements appartenant à l’utilisateur actuel :

Note

Si RequiredColumns retourne une liste vide et que les méthodes au niveau de l’enregistrement du gestionnaire n’utilisent record.Idque , aucune colonne supplémentaire n’est ajoutée à la requête. La owner propriété est toujours fournie par la plateforme, quel que soit RequiredColumnsle facteur .

Intercepteurs de filtres de requête FetchXML

En plus de la sécurité au niveau des tables et des enregistrements, PowerPortalsPro prend en charge IFetchXmlQueryFilterInterceptor — une interface qui vous permet de modifier les requêtes FetchXML avant leur exécution. Cela est utile pour imposer un filtrage au niveau des lignes, par exemple pour s’assurer qu’un utilisateur ne puisse voir que les enregistrements qui lui appartiennent ou qui lui appartiennent à son équipe.

IFetchXmlQueryFilterInterceptor étend ITablePermissionHandler, donc chaque intercepteur définit également des permissions au niveau de la table via la Table propriété et les méthodes d’autorisation standard. La méthode de l’intercepteur OnQueryAsync n’est appelée que pour les requêtes qui ciblent sa table spécifiée.

Contrairement aux gestionnaires de permissions au niveau des enregistrements qui évaluent chaque enregistrement après récupération, les intercepteurs filtres de requête modifient la requête avant qu’elle n’atteigne Dataverse. Les enregistrements filtrés ne sont jamais récupérés, ce qui améliore les performances et la sécurité — et, surtout, permet de garder la pagination en grille et les comptages totaux précis, car le filtrage appliqué après la récupération laisserait les pages courtes et ferait mal compter les totaux de la situation.

1. Créer un intercepteur de filtre de requête

Implémentez IFetchXmlQueryFilterInterceptor, définissez la Table propriété au nom logique de la table, implémentez les méthodes de permission, et utilisez l’in FetchXMLBuilder OnQueryAsync pour ajouter des filtres à la requête. L’enregistrement FetchXmlParameters fournit le EntityReferencefichier . FetchXMLBuilder

L’exemple suivant restreint les requêtes sur la contact table pour ne retourner que l’enregistrement correspondant à l’utilisateur actuel :

2. Enregistrer dans l’injection de dépendance

Enregistrez votre intercepteur à la fois comme an IFetchXmlQueryFilterInterceptor et an ITablePermissionHandler afin que les permissions de filtrage des requêtes et de niveau tableau soient appliquées. Plusieurs intercepteurs peuvent être enregistrés et chacun sera exécuté pour des requêtes ciblant sa table.

Conseil

Parce que IFetchXmlQueryFilterInterceptor étend ITablePermissionHandler, une seule classe gère à la fois les permissions au niveau de la table et le filtrage au niveau requête. La OnQueryAsync méthode n’est invoquée que pour les requêtes correspondant à la propriété de l’intercepteur Table , il n’est donc pas nécessaire de vérifier le nom de la table à l’intérieur de la méthode.

Classes de base intégrées

Le cadre fournit des classes de base pour simplifier les schémas de sécurité courants :

Référence API

ITablePermissionHandler Interface

Propriétés

Nom
Type
Par défaut
Description
Tablestring
Nom logique de la table à laquelle ce gestionnaire de permissions s’applique.
Nom: Table
Type: string
Description: Nom logique de la table à laquelle ce gestionnaire de permissions s’applique.

Méthodes

Nom
Paramètres
Type
Description
CanAppendAsyncGuid? userId
Task<bool>
Méthode pour déterminer si un utilisateur doit pouvoir ajouter un enregistrement.
CanAppendToAsyncGuid? userId
Task<bool>
Méthode pour déterminer si un utilisateur devrait pouvoir ajouter à un enregistrement.
CanCreateAsyncGuid? userId
Task<bool>
Méthode pour déterminer si un utilisateur doit pouvoir créer un enregistrement.
CanDeleteAsyncGuid? userId
Task<bool>
Méthode pour déterminer si un utilisateur doit pouvoir supprimer un enregistrement.
CanReadAsyncGuid? userId
Task<bool>
Méthode pour déterminer si un utilisateur doit pouvoir lire un enregistrement.
CanUpdateAsyncGuid? userId
Task<bool>
Méthode pour déterminer si un utilisateur doit pouvoir mettre à jour un enregistrement.
Nom: CanAppendAsync
Paramètres: Guid? userId
Type: Task<bool>
Description: Méthode pour déterminer si un utilisateur doit pouvoir ajouter un enregistrement.
Nom: CanAppendToAsync
Paramètres: Guid? userId
Type: Task<bool>
Description: Méthode pour déterminer si un utilisateur devrait pouvoir ajouter à un enregistrement.
Nom: CanCreateAsync
Paramètres: Guid? userId
Type: Task<bool>
Description: Méthode pour déterminer si un utilisateur doit pouvoir créer un enregistrement.
Nom: CanDeleteAsync
Paramètres: Guid? userId
Type: Task<bool>
Description: Méthode pour déterminer si un utilisateur doit pouvoir supprimer un enregistrement.
Nom: CanReadAsync
Paramètres: Guid? userId
Type: Task<bool>
Description: Méthode pour déterminer si un utilisateur doit pouvoir lire un enregistrement.
Nom: CanUpdateAsync
Paramètres: Guid? userId
Type: Task<bool>
Description: Méthode pour déterminer si un utilisateur doit pouvoir mettre à jour un enregistrement.

ITableRecordPermissionHandler Interface

Propriétés

Nom
Type
Par défaut
Description
RequiredColumnsList<string>
Liste des noms logiques de colonnes à récupérer pour que ce gestionnaire puisse évaluer les permissions au niveau de l’enregistrement.
Tablestring
Nom logique de la table à laquelle ce gestionnaire de permissions s’applique.
Nom: RequiredColumns
Type: List<string>
Description: Liste des noms logiques de colonnes à récupérer pour que ce gestionnaire puisse évaluer les permissions au niveau de l’enregistrement.
Nom: Table
Type: string
Description: Nom logique de la table à laquelle ce gestionnaire de permissions s’applique.

Méthodes

Nom
Paramètres
Type
Description
CanAppendAsyncGuid? userId
TableRecord record
Task<bool>
Méthode pour déterminer si un utilisateur doit pouvoir ajouter l’enregistrement fourni.
CanAppendToAsyncGuid? userId
TableRecord record
Task<bool>
Méthode pour déterminer si un utilisateur doit pouvoir ajouter à l’enregistrement fourni.
CanCreateAsyncGuid? userId
TableRecord record
Task<bool>
Méthode pour déterminer si un utilisateur doit pouvoir créer l’enregistrement fourni.
CanDeleteAsyncGuid? userId
TableRecord record
Task<bool>
Méthode pour déterminer si un utilisateur doit pouvoir supprimer l’enregistrement fourni.
CanReadAsyncGuid? userId
TableRecord record
Task<bool>
Méthode pour déterminer si un utilisateur doit pouvoir lire l’enregistrement fourni.
CanUpdateAsyncGuid? userId
TableRecord recordWithUpdates
TableRecord currentRecord
Task<bool>
Méthode pour déterminer si un utilisateur doit pouvoir mettre à jour l’enregistrement fourni.
Nom: CanAppendAsync
Paramètres: Guid? userId
TableRecord record
Type: Task<bool>
Description: Méthode pour déterminer si un utilisateur doit pouvoir ajouter l’enregistrement fourni.
Nom: CanAppendToAsync
Paramètres: Guid? userId
TableRecord record
Type: Task<bool>
Description: Méthode pour déterminer si un utilisateur doit pouvoir ajouter à l’enregistrement fourni.
Nom: CanCreateAsync
Paramètres: Guid? userId
TableRecord record
Type: Task<bool>
Description: Méthode pour déterminer si un utilisateur doit pouvoir créer l’enregistrement fourni.
Nom: CanDeleteAsync
Paramètres: Guid? userId
TableRecord record
Type: Task<bool>
Description: Méthode pour déterminer si un utilisateur doit pouvoir supprimer l’enregistrement fourni.
Nom: CanReadAsync
Paramètres: Guid? userId
TableRecord record
Type: Task<bool>
Description: Méthode pour déterminer si un utilisateur doit pouvoir lire l’enregistrement fourni.
Nom: CanUpdateAsync
Paramètres: Guid? userId
TableRecord recordWithUpdates
TableRecord currentRecord
Type: Task<bool>
Description: Méthode pour déterminer si un utilisateur doit pouvoir mettre à jour l’enregistrement fourni.

IFetchXmlQueryFilterInterceptor Interface

Propriétés

Nom
Type
Par défaut
Description
Tablestring
Nom logique de la table à laquelle ce gestionnaire de permissions s’applique.
Nom: Table
Type: string
Description: Nom logique de la table à laquelle ce gestionnaire de permissions s’applique.

Méthodes

Nom
Paramètres
Type
Description
CanAppendAsyncGuid? userId
Task<bool>
Méthode pour déterminer si un utilisateur doit pouvoir ajouter un enregistrement.
CanAppendToAsyncGuid? userId
Task<bool>
Méthode pour déterminer si un utilisateur devrait pouvoir ajouter à un enregistrement.
CanCreateAsyncGuid? userId
Task<bool>
Méthode pour déterminer si un utilisateur doit pouvoir créer un enregistrement.
CanDeleteAsyncGuid? userId
Task<bool>
Méthode pour déterminer si un utilisateur doit pouvoir supprimer un enregistrement.
CanReadAsyncGuid? userId
Task<bool>
Méthode pour déterminer si un utilisateur doit pouvoir lire un enregistrement.
CanUpdateAsyncGuid? userId
Task<bool>
Méthode pour déterminer si un utilisateur doit pouvoir mettre à jour un enregistrement.
OnQueryAsyncFetchXMLBuilder fetchXmlBuilder
FetchXmlParameters parameters
Task<FetchXMLBuilder>
Appelé pour permettre la modification d’une requête FetchXML avant son exécution.
Nom: CanAppendAsync
Paramètres: Guid? userId
Type: Task<bool>
Description: Méthode pour déterminer si un utilisateur doit pouvoir ajouter un enregistrement.
Nom: CanAppendToAsync
Paramètres: Guid? userId
Type: Task<bool>
Description: Méthode pour déterminer si un utilisateur devrait pouvoir ajouter à un enregistrement.
Nom: CanCreateAsync
Paramètres: Guid? userId
Type: Task<bool>
Description: Méthode pour déterminer si un utilisateur doit pouvoir créer un enregistrement.
Nom: CanDeleteAsync
Paramètres: Guid? userId
Type: Task<bool>
Description: Méthode pour déterminer si un utilisateur doit pouvoir supprimer un enregistrement.
Nom: CanReadAsync
Paramètres: Guid? userId
Type: Task<bool>
Description: Méthode pour déterminer si un utilisateur doit pouvoir lire un enregistrement.
Nom: CanUpdateAsync
Paramètres: Guid? userId
Type: Task<bool>
Description: Méthode pour déterminer si un utilisateur doit pouvoir mettre à jour un enregistrement.
Nom: OnQueryAsync
Paramètres: FetchXMLBuilder fetchXmlBuilder
FetchXmlParameters parameters
Type: Task<FetchXMLBuilder>
Description: Appelé pour permettre la modification d’une requête FetchXML avant son exécution.