La sécurité est un sujet majeur dans la conception d’une solution décisionnelle,  car elle a notamment pour objectif de définir les modalités d’accès à des données qui peuvent s’avérer stratégiques pour l’entreprise.

En matière de Business Intelligence, les questions relatives à la sécurité sont à la fois liées à des exigences métiers et opérationnelles (ex : quels sont les utilisateurs habilités à accéder aux données, avec quelles restrictions de filtrage…), mais également techniques et architecturales (le mode d’authentification à privilégier, quel annuaire ou quel référentiel de sécurité utiliser…).

Après un premier article sur la confidentialité des données et la séparation des rôles, nous allons cette fois-ci expliquer comment mettre en place la sécurité d’une base multidimensionnelle Analysis Services (cube OLAP) afin d’assurer un  contrôle des accès aux données.

Problématique

  • Evaluer les besoins opérationnels en termes de sécurisation des accès aux données
  • Comprendre les possibilités de gestion des accès à un cube multidimensionnel

Bénéfices

  • Une garantie de confidentialité des données sensibles de l’entreprise.
  • Une stratégie de sécurité adaptée au besoin opérationnel et offrant le meilleur niveau de performance
  • Une adoption des bonnes pratiques en termes de sécurisation des cubes multidimensionnels ;

 

Concevoir une stratégie de sécurité

La phase de réflexion concernant la sécurité d’une base de données multidimensionnelle intervient parfois sur des projets alors que le développement est quasiment terminé.

Ce type de situation peut avoir un impact négatif sur le projet, notamment au niveau du planning, car pour établir une sécurité solide et efficace, il faut bien être conscient des éléments à intégrer à la solution dès le départ. Si certains éléments n’ont pas été intégrés au magasin de données (Datamart) sur lequel se repose la base de données multidimensionnelle, il faudra développer à nouveau certaines parties de la solution.

Il est donc primordial de bien prendre le temps d’intégrer dans cette phase de réflexion, une logique métier afin de mettre en place les règles conformes à la politique de votre entreprise et de son écosystème.

 

La sécurité dans un cube Analysis Services

Le mécanisme de sécurité d’Analysis Services s’appuie sur un gestionnaire de sécurité, qui permet de gérer les autorisations propres à chaque utilisateur. Lorsqu’un utilisateur se connecte au cube, le gestionnaire de sessions vérifie si une session existe pour cet utilisateur dans le cache de sessions. Si tel n’est pas le cas, alors le gestionnaire de sécurité est appelé pour évaluer un contexte de sécurité en fonction de règles puis de l'attribuer à l'utilisateur.

 

La mise en place de la sécurité des bases de données multidimensionnelles dans Analysis Services s’articule autour de l’utilisation de rôles. Un rôle permet d’associer à des utilisateurs des autorisations sur les différents objets d’une base de données multidimensionnelle.

Il existe beaucoup d’article (http://technet.microsoft.com/fr-fr/library/ms189696.aspx) qui décrivent comment créer des rôles et comment définir une sécurité sur les objets de la base de données Analysis Services.,

L’objectif de cet article est de se focaliser d’avantage sur les spécificités de ces rôles en éclaircissant quelques points qui soulèvent souvent quelques interrogations :

  • Si un utilisateur est membre de plusieurs rôles, une union de ses rôles sera effectuée (et non pas une intersection). Par conséquent si un utilisateur est déclaré comme Administrateur au sein d’un rôle, ses droits ne pourront pas être révoqués ou limités par un autre rôle. 
  • Lorsque plusieurs centaines de rôles sont créés sur une base Analysis Services, il est primordial d’avoir une nomenclature définie avec une convention propre afin de retrouver facilement l’information recherchée. Les noms de rôles sont limités à 100 caractères.
  • Il est préférable que les membres d’un rôle ne soit pas des utilisateurs mais plutôt des groupes d’utilisateurs. Ainsi la gestion des membres se fait non pas à travers Analysis Services mais à travers la gestion de ces groupes.

 

Sécurité des données

La sécurité des données d’une base de données Analysis Services se fait au travers des rôles et peut être effectuée de deux manières :

  • En limitant l’accès des membres associés aux dimensions de la base de données ou des cubes à l’aide du concepteur de Rôle, de manière graphique ou en définissant des expressions MDX :

  

 

Ainsi on peut limiter l’accès aux données d’un pays aux utilisateurs d’un rôle donné :

Sur la seconde illustration, le total n’est pas égal à la donnée du seul pays auquel le rôle a accès.

Ceci peut être configuré au niveau des rôles en activant ou non la propriété « Enable Visual Totals ». En revanche, il faut préciser que l’activation de cette propriété a un coût non négligeable sur la performance car les agrégations sont calculées lors de la requête et ne proviennent pas d’agrégats pré calculés.

 

  • Il est possible de définir des expressions MDX afin de limiter la visibilité à certaines cellules des cubes sans limiter l’accès aux données. Les cellules pour lesquelles est défini un droit de lecture seront affichées avec la valeur #N/A au lieu de leur valeur réelle. Trois niveaux de droits sont disponibles : lecture, simple, lecture/écriture et lecture du contingent.

Voici ce qui est affiché à l’utilisateur lorsque l’on sécurise les cellules d’un cube avec une lecture simple :

On constate que l’utilisation d’une mesure calculée engendre une faille de sécurité puisque l’on peut recalculer les valeurs des cellules masquées à l’aide des données des autres mesures. C’est ce que permet d’éviter la lecture du contingent en n’affichant la valeur d’une cellule si et seulement si, l’utilisateur a accès aux cellules utilisées pour calculer celle-ci.

La sécurité sur les cellules est très puissante mais peut empêcher le moteur d’Analysis Services de faire appel au cache, même pour des calculs déjà effectués. Il est donc conseillé de ne l’utiliser qu’en cas de nécessité.

Les erreurs à éviter

  • Attention à ne pas sécuriser des dimensions de base de données à partir desquelles sont créées des dimensions de rôle actif (ou Role-Playing dimensions). Les permissions des dimensions de cubes héritant des permissions de dimensions de base de données, l’expression passée par le parent dans le cadre d’une dimension de rôle actif ne sera pas valide et provoquera une erreur. Pour éviter ce problème, surchargez la sécurité directement au niveau des dimensions de rôle actif.
  • La même typologie d’erreur surviendra en déclarant la sécurité sur un attribut d’une dimension de base de données qui n’est pas disponible dans un cube, et ce même si l’utilisateur ne se connecte pas à celui-ci. 
  • Sécuriser un membre appelé dans un script MDX d’un cube et auquel le rôle n’a pas accès entrainera une erreur. Les expressions de sécurité étant évaluées avant les scripts MDX, ceux-ci tenteront alors de faire appel à des éléments bloqué pour cette utilisateur et affichera une erreur.

 

Tester la sécurité

Un fois le contexte de sécurité mis en place, il faut ensuite être en mesure de le tester. Pour cela, nous allons utiliser Excel qui reste aujourd'hui un outil d’analyse très utilisé. Nous allons donc pouvoir tester la sécurité directement sur les rapports finaux en modifiant leur chaine de connexion. Deux approches existent :

  • Se placer dans le contexte d’un Rôle donné :

Provider=MSOLAP.5;Persist Security Info=True;Data Source=localhost;MDX Compatibility=1;Roles= AdventureWorks_Australia_SalesAndMarketing;Safety Options=2;MDX Missing Member Mode=Error

  • Se placer dans le contexte ‘un utilisateur donné :

Provider=MSOLAP.5;Persist Security Info=True;Data Source=localhost;MDX Compatibility=1;EffectiveUserName=EUROPE\john.doe;Safety Options=2;MDX Missing Member Mode=Error

Ces deux propriétés ne peuvent être utilisées que par des administrateurs de la base de données multidimensionnelle.

La propriété « EffectiveUserName » permet de se placer dans le contexte de sécurité d’un utilisateur mais en aucun cas on ne pourra créer une connexion en son nom.

Comme vous le voyez, bien qu’on ait spécifié l’utilisateur John Doe comme valeur de la propriété dans la chaine de connexion, c’est l’utilisateur (et administrateur) « mmineo » qui effectue la requête. En revanche on constate que la session est initialisée avec le rôle « AdventureWorks_Australia_SalesAndMarketing» dont fait partie l’utilisateur John Doe. Si la requête avait été effectuée avec les droits de l’utilisateur mmineo, une étoile apparaitra, suivie de l’ensemble des rôles de la base de données (comportement signifiant qu’un administrateur initialise une session) :

 

Pour résumer, sécuriser vos données en utilisant les fonctionnalités de base mise à votre disposition par le produit, reste la manière la plus efficace et la plus performante pour votre stratégie de sécurité car il existe un mécanisme de mutualisation du cache au sein de chacun des rôles. Les utilisateurs d’un même rôle bénéficieront de la mise en cache de certains calculs déjà effectués par des utilisateurs du même rôle.

Cette approche basée sur des rôles de sécurité « figés » est très adaptée lorsque les droits attribués aux utilisateurs sont relativement stables (pas de sécurité « temps réel » à gérer), et que le nombre de rôle à créer en fonction des droits à gérer reste maitrisé.

Dans le cadre de certains projets, il est cependant indispensable de mettre en place un sécurité dynamique pour les raisons suivantes :

-       Connecter la sécurité à partir d’un référentiel existant

-       Application en temps réel des règles de sécurité

-       Nombreuses combinaisons d’axes d’analyse à sécuriser en fonction des populations d’utilisateurs

-       Granularité de sécurité très fine, par utilisateur

 

Plus de souplesse avec une sécurité dynamique

Cette partie de l’article sera consacrée à la mise en place d’une sécurité dynamique en démontrant deux méthodes souvent utilisées chez les clients.

 

Stockez la sécurité dans votre cube

Cette méthode consiste à ajouter à votre base de données relationnelle et multidimensionnelle un certain nombre d’éléments :

  • Une nouvelle table contenant la liste des utilisateurs.
  • Une nouvelle table de relation entre la table des utilisateurs et la dimension à sécuriser. 
  • Une dimension utilisateur créée à partir de la table utilisateur précédemment crée. .
  • Un groupe de mesure basé sur la table de relation entre les utilisateurs et la dimension à sécuriser.

Ce principe utilise un unique rôle où l’on va définir une expression MDX comme suit sur un des attributs de la dimension à sécuriser :

NonEmpty (

       DimensionToSecure.Attribute.Members,

       (

             StrToMember ("[Users].[User].[" + UserName () + "]"),

             [Measures].[New Measure Group]

       )

)

Interrogation d’une base de données relationnelle

Cette approche est particulière dans le sens où elle est nécessite une légère compétence en développement .NET. En effet, il est possible de déployer au sein d’une instance ou d’une base de données Analysis Services des assembly qui permettent d’ajouter de nouvelles fonctionnalités (principalement des fonctions MDX).

Voici le schéma de cette approche :

  • Une base de données relationnelle, générallement sous-jacente au cube, contient les règles de sécurité (ex : table utilisateurs, table des membres à sécuriser et tables de relation entre ces deux dernières).
  • Une assembly .NET custom, faisant la jonction entre la base de données et la sécurité du cube,  est déployée sur le serveur.
  • Un rôle SSAS est créé, avec une expression de sécurité en MDX faisant appel à une fonction exposée par l'assembly custom (l'identité de l'utilisateur est passée en paramètre).
  • L'assembly interroge la base de données à travers une procédure stockée, et renvoie au Security Manager le jeu de données accessibles pour l'utilisateur 
  • L'utilisateur peut alors interroger le cube à travers un contexte de sécurité qui lui est propre.

 

Les deux approches sont assez différentes l’une de l’autre, le choix se fera notamment en fonction du nombre d’axes à sécuriser. L’utilisation de l’assembly paraît plus simple à mettre en place, notamment lorsque l’on souhaite mettre en place une sécurité sur un certain nombre d’axes de données alors que la modification de la structure des cubes peut s’avérer plus performante, mais plus complexe à mettre en place.

La sécurité dynamique offre l’énorme avantage d’une gestion plus souple en supprimant la dépendance avec les outils d’administration natifs pour n’agir finalement que sur des données dans des tables. En revanche, il y a un coût non négligeable à son utilisation en termes de performance. L’appel à la fonction "Username"  dans les expressions MDX des rôles (pour renvoyer l'identité de l'utilisateur), empêche la mutualisation du cache et l’utilisateur ne bénéficiera donc pas des calculs déjà effectués pour les autres utilisateurs.

 

Accompagner les clients avec des outils personnalisés  

Si vous avez opté pour une sécurité classique, vous avez peut-être dans votre solution un nombre de rôles conséquent ce qui ne pose pas de problèmes en soit, mais au fur et à mesure que votre entreprise évolue, les besoins changent et votre contexte de sécurité aussi. Il peut donc s’avérer difficile de gérer ce grand nombre de rôles.

Des outils peuvent donc être développés à l’aide de la librairie AMO.net afin de faciliter la gestion de votre base de données Analysis Services en général et par conséquent, des rôles de sécurité qui y sont définis.

Voici quelques exemples de cas d’utilisations mis en place chez des clients afin de les accompagner dans la conception et la maintenance de leur sécurité : 

  • Il est possible de scripter la création de votre contexte de sécurité, en bouclant sur un fichier ou une table dans laquelle vous aurez défini les différents éléments à créer. Voici un exemple de création d’un rôle avec AMO.net :

Try {

Server asserver = new Server();

asserver.Connect("localhost");

// Connection au serveur

Database asdatabase =asserver.Databases["Adventure Works DW 2008R2"]; // Creation de l'objet database

// Creation du Role

Role roleAustraliaSalesAndMarketing =asdatabase.Roles.Add("AdventureWorks_Australia_SalesAndMarketing");

//Ajout d'un membre au role

roleAustraliaSalesAndMarketing.Members.Add(new RoleMember("EUROPE\\john.doe")); // Ajout d'utilisateurs

roleAustraliaSalesAndMarketing.Update(UpdateOptions.AlterDependents, UpdateMode.CreateOrReplace);

// Droit de lecture sur le membre Australie des territoires de ventes

DimensionPermission dp = asdatabase.Dimensions["Dim Sales Territory"].DimensionPermissions.Add(roleAustraliaSalesAndMarketing.ID);

AttributePermission ap = dp.AttributePermissions.Add("Sales Territory Country");

ap.AllowedSet = "{[Sales Territory].[Sales Territory Country].&[Australia]}";

dp.Update(UpdateOptions.AlterDependents, UpdateMode.CreateOrReplace);

// Droit de lecture sur le cube Adventure Works

Cube advWorksCube = asdatabase.Cubes["Adventure Works"];

CubePermission cp = advWorksCube.CubePermissions.Add(roleAustraliaSalesAndMarketing.ID);

cp.Read = ReadAccess.Allowed;

// Droit de lecture du Departement Sales and Marketing

CubeDimensionPermission cdp = new CubeDimensionPermission("Dim Department Group");

AttributePermission cap = cdp.AttributePermissions.Add("Parent Department Group Key");

cap.AllowedSet = "{[Department].[Departments].&[7]}";

cp.DimensionPermissions.Add(cdp);

cp.Update(UpdateOptions.AlterDependents, UpdateMode.CreateOrReplace);

asserver.Disconnect();

}

catch (OutOfMemoryException oomex){...}

catch (ConnectionException cex){...}

catch (ArgumentNullException anex){...}

catch (OperationException opex){...}

catch (AmoException amoex){...}

catch (Exception ex){...}

  • Créer des rapports permettant d’avoir une vue détaillée sur l’ensemble de la stratégie de sécurité, tâche relativement complexe à faire avec les outils de gestion classique.
  • Organiser la migration d’une stratégie de sécurité d’un environnement à un autre.
  • Développement d’écrans de gestion personnalisés permettant de déléguer la gestion des autorisations sur les données à des utilisateurs métiers clés.

 

L’expertise Microsoft Consulting Services au service de ses clients

Comme vous avez pu le voir tout au long de cet article, la sécurité d’une base de données multidimensionnelle est un point d’attention important à ne pas sous-estimer en phase de conception d’une solution décisionnelle.

Microsoft Consulting Services et l’équipe Data Insight propose à ses clients de les accompagner grâce à une expertise poussée sur ces sujets, aussi bien dans la phase d’étude du projet que dans sa conception ou sur des missions plus courte de validation ou d’audit.

Voici quelques exemples de clients pour lesquels Microsoft Consulting Services a engagé ses experts pour sécuriser la mise en œuvre de solutions décisionnelles :

-       Banques françaises d’investissements

-       Leader mondial dans les produits cosmétiques

-       Leader français dans la distribution d’énergie

-       Acteur majeur dans la gestion locative

 

Pour plus d’informations sur les offres packagées Microsoft Consulting Services, rendez-vous sur http://www.microsoft.com/france/services

Plus d’informations sur les blogs « SQL Server chez les clients ».

 

Marc Mineo, Consultant Data Insights, Microsoft Consulting Services

Issu du graduate program de Microsoft (programme MACH), permettant d’intégrer des jeunes diplômés tout en leur offrant une formation riche pour une meilleur intégration dans l’entreprise, je participe à des missions en tant qu’expert sur les outils de Business Intelligence, avec un certain attrait pour la visualisation des données et la conception de bases de données multidimensionnelles.