Parfois, lorsque vous appliquez la Row Level Security (RLS) dynamique dans Power BI, vous souhaitez utiliser plusieurs critères et pouvoir les combiner avec une logique ET (tous les critères) ou bien une logique OU (au moins un des critères).
Cela peut s’avérer un peu délicat, notamment car le comportement des relations permet généralement de filtrer selon un seul champ.
Dans cet article, nous allons utiliser la puissance du langage DAX pour implémenter la Row Level Security sur nos données avec plusieurs critères et selon tout type de logique de filtre.
Petit rappel : Qu’est-ce que la RLS dynamique ?
La Row Level Security ou Sécurité au niveau des lignes dans Power BI, permet de contrôler que chaque utilisateur ne voit que les données qui lui sont autorisées.
- La RLS statique applique les règles définies manuellement pour chaque rôle, et les utilisateurs sont assignés à ces rôles.
- La RLS dynamique applique des règles d’accès en fonction de l’utilisateur connecté. Cette approche est plus flexible mais plus complexe à mettre en oeuvre.
Exemple pour illustrer l’utilité de la RLS dynamique :
Une société compte plusieurs responsables par région et de niveau hiérarchique différent qui doivent accéder uniquement aux données de leur région et de leur niveau hiérarchique. La RLS dynamique va permettre de filtrer automatiquement les données affichées en fonction de l’identité de l’utilisateur.
Grâce à cette approche, vos données seront sécurisées et chaque utilisateur verra uniquement ce qui lui est destiné.
Scenario
Imaginez la table de données financières de la société Star suivante :
Jean-Luc et Lionel travaillent à la direction commerciale du Groupe ⭐. Jean-Luc doit voir les segments Partenaires et Services publics, ainsi que le pays Allemagne, et les produits VTT. Lionel doit voir les segments BtoB et Entreprises, ainsi que le pays USA, et les produits Vélo.
On a donc 3 critères de filtre des données basés sur les champs Segment, Pays et Produit.
Ce cas est typique dans les entreprises où j’ai eu à mettre en place une RLS dynamique multi-critères.
Voyons comment implémenter cette solution dans ce guide pas à pas. En suivant ces étapes, vous surmonterez facilement le défi..
Définition des tables et des relations
On remarque que la table de données ne comporte pas de champs Utilisateur, donc impossible de filtrer directement sur l’utilisateur via la RLS comme ceci :
[Email] = USERPRINCIPALNAME()
Nous devons donc commencer par créer une table Utilisateurs DimUsers pour pouvoir filtrer les données selon l’utilisateur connecté :
Ensuite, nous devons préciser les règles d’accès pour chaque utilisateur. Pour cela, on crée une table DimUsersRules comportant les champs User et une colonne par champs de données à filtrer :
Nous avons ainsi défini sur quels champs et sur quelles valeurs de ces champs la Row Level Security devra s’appliquer pour chacun des utilisateurs.
Chargeons ces tables dans le modèle sémantique de notre rapport Power BI. Puis établissons la relation entre les tables DimUsers et DimUsersRules :
Pour implémenter la RLS dynamique multi-critères, nous ne pouvons pas nous appuyer uniquement sur les relations entre les tables pour appliquer les filtres, car la table Finances ne contient aucune information sur l’utilisateur et ne peut donc être reliée aux tables utilisateurs. Cela signifie que nous devons utiliser des expressions en DAX pour filtrer les données, et que les 2 tables utilisateurs ajoutées au modèle resteront déconnectées des autres tables du modèle.
RLS dynamique avec logique ET : tous les critères sont respectés
Commençons par décrire le cas où tous les critères doivent être respectés pour filtrer les données de la table Finances.
Ainsi Jean-Luc n’aura accès qu’aux lignes de la table Finances pour lesquelles :
- Segment est égal à Partenaires ou Services publics ET
- Pays est égal à Allemagne ET
- Produit est égal à VTT
- Définissons les rôles d’accès dans Power BI, via le menu Modélisation -> Gérer les rôles :
2. Créons un rôle Admin pour lequel aucune restriction d’accès ne s’applique (cela peut être utile pour affecter ce rôle à un Directeur Général ou Directeur Financier), et un rôle Utilisateur pour lequel la RLS dynamique s’applique.
Pour le rôle Admin, j’ai l’habitude de définir une expression DAX sur la table DimUsers, même si elle n’effectuera aucun filtre sur les données, par exemple l’expression suivante renvoie toujours vrai :
1==1
3. Pour le rôle Utilisateur, définissons 2 filtres, un sur la table des utilisateurs et un autre sur la table des données Finances.
Le filtre sur la table Utilisateur permet d’obtenir les données de l’utilisateur actuel :
DimUsers[Email] = USERPRINCIPALNAME()
Comme la table DimUsers est reliée à DimUsersRules par une relation unidirectionnelle, DimUserRules sera également filtrée sur les règles d’accès de l’utilisateur actuel.
L’autre filtre est défini sur la table des données financières. C’est ici que nous implémentons la logique de filtres et la prise en compte de nos 3 critères sur les champs de données Segment / Pays / Produit :
VAR ThisUser = USERPRINCIPALNAME() VAR FinanceDataInScope = SELECTCOLUMNS ( FILTER ( Finances, ------- Critère 1 ------- Finances[Segment] IN SELECTCOLUMNS ( FILTER( DimUsersRules, RELATED(DimUsers[Email]) = ThisUser ), "Segment", DimUsersRules[Segment] ) && ------- Critère 2 ------- Finances[Pays] IN SELECTCOLUMNS ( FILTER( DimUsersRules, RELATED(DimUsers[Email]) = ThisUser ), "Pays", DimUsersRules[Pays] ) && ------- Critère 3 ------- Finances[Produit] IN SELECTCOLUMNS ( FILTER( DimUsersRules, RELATED(DimUsers[Email]) = ThisUser ), "Produit", DimUsersRules[Produit] ) ), "RowIndex", Finances[RowIndex] ) RETURN Finances[RowIndex] IN FinanceDataInScope
Explication pour le premier critère :
Le bout de formule ci-dessous vérifie que les valeurs de la colonne Finances[Segment] sont comprises dans les valeurs fournies dans la colonne Segment de la table DimUsersRules pour l’utilisateur actuel.
Ainsi, pour Jean-Luc le champs Segment de la table Finances sera filtré sur les valeurs “Partenaires” et “Services publics”.
-- Critère 1 -- Finances[Segment] IN SELECTCOLUMNS( FILTER(DimUsersRules, RELATED(DimUsers[Email]) = ThisUser), "Segment", DimUsersRules[Segment] )
A noter :
- && entre chaque critère signifie AND, donc on applique tous les critères à la table Finances pour créer le filtre sur les données.
- Il est certainement possible d’améliorer les performances de cette expression de filtre. Ici le jeu de données est relativement léger, mais il n’est pas recommandé pour des gros jeux de données de filtrer sur la table entière de données comme je l’ai fait ici avec le FILTER ( Finances, ..)
Enfin, on retourne uniquement lignes de la table Finances qui sont filtrées par nos 3 critères :
RETURN Finances[RowIndex] IN FinanceDataInScope
RLS dynamique avec logique OU : au moins un des critères doit être respecté
Si on ne veut pas que tous les critères s’appliquent simultannément aux données, il faut réécrire l’expression DAX sur la table Finances.
Par exemple, maintenant on souhaite que Jean-Luc ait accès à :
- Toutes les lignes des segments Partenaire et Services publics OU bien
- Toutes les lignes du pays Allemagne OU bien
- Toutes les lignes du produit VTT
Il suffit qu’un seul critère sur un champs soit respecté pour retourner les lignes associées aux valeurs du champs définies dans les règles d’accès.
Voici la formule modifiée :
VAR ThisUser = USERPRINCIPALNAME() VAR FinanceDataInScope = SELECTCOLUMNS ( FILTER ( Finances, ------- Critère 1 ------- Finances[Segment] IN SELECTCOLUMNS ( FILTER( DimUsersRules, RELATED(DimUsers[Email]) = ThisUser ), "Segment", DimUsersRules[Segment] ) || ------- Critère 2 ------- Finances[Pays] IN SELECTCOLUMNS ( FILTER( DimUsersRules, RELATED(DimUsers[Email]) = ThisUser ), "Pays", DimUsersRules[Pays] ) || ------- Critère 3 ------- Finances[Produit] IN SELECTCOLUMNS ( FILTER( DimUsersRules, RELATED(DimUsers[Email]) = ThisUser ), "Produit", DimUsersRules[Produit] ) ), "RowIndex", Finances[RowIndex] ) RETURN Finances[RowIndex] IN FinanceDataInScope
Il suffit en fait de remplacer les && par || , qui signifie OR.
Vérification du résultat de la RLS
Publions le rapport dans Power BI Service, puis clic droit sur le modèle sémantique et “Sécurité” pour affecter les utilisateurs aux rôles :
Astuce: Assurez-vous de tester vos filtres avec différents utilisateurs pour vérifier leur bon fonctionnement.
- Pour le rôle Admin, on vérifie bien qu’aucune ligne de données n’est filtrée par la RLS (le jeu de données comportait 700 lignes au total) :
2. Pour le rôle Utilisateur, chaque utilisateur ne voit que ses lignes de données en fonction des critères qui lui sont propres définis et dans la table DimUsersRules :
Conclusion
La Row Level Security (RLS) dynamique multi-critères est un art qui allie modélisation avancée en DAX et relations entre les tables.
✅ Pour obtenir le résultat souhaité, il est crucial de savoir comment définir la logique d’accès sécurisé aux données en expressions DAX.
✅ Dans cet article, vous avez appris à implémenter une RLS multi-critères avec des logiques ET et OU dans Power BI.
Si vous avez des questions ou des commentaires, n’hésitez pas à les partager ci-dessous. Je serai ravi d’échanger avec vous sur ce sujet.
TELECHARGER LE FICHIER D’EXEMPLE
Téléchargez le fichier Power BI de ce tutoriel.
Entrez votre email pour télécharger le fichier (obligatoire)
RLS multi-critères dans Power BI
Envoyer le lien de téléchargement à :
Merci d’avoir suivi cet article !!
Expérimentez ces fonctions dans vos propres rapports Power BI ou contactez-moi pour une expertise approfondie et des conseils personnalisés.
Cliquez ici pour accéder à la formation complète pour maîtriser Power BI