Aller au contenu

Contrôle d'accès et rôles

Le modèle de contrôle d’accès de Mondrian vous permet de découper votre schema en rôles. Un rôle est un ensemble nommé d’autorisations et de refus qui couvre l’ensemble du schema — des cubes visibles jusqu’aux membres individuels qu’un utilisateur a le droit de voir. Vous définissez les rôles directement dans votre fichier de schema, et Saiku Cloud les applique lorsqu’il établit une connexion au nom d’un utilisateur.

Définir un rôle

Les éléments <Role> sont des enfants directs de <Schema>, placés après le dernier <Cube>. Voici un exemple complet :

- name: "California manager"
schema_grant:
access: "none"
cubes:
- cube: "Sales"
access: "all"
dimensions:
- dimension: "[Measures]"
access: "all"
hierarchies:
- hierarchy: "[Store]"
access: "custom"
top_level: "[Store].[Store Country]"
members:
- member: "[Store].[USA].[CA]"
access: "all"
- member: "[Store].[USA].[CA].[Los Angeles]"
access: "none"
- hierarchy: "[Customers]"
access: "custom"
top_level: "[Customers].[State Province]"
bottom_level: "[Customers].[City]"
members:
- member: "[Customers].[USA].[CA]"
access: "all"
- member: "[Customers].[USA].[CA].[Los Angeles]"
access: "none"
- hierarchy: "[Gender]"
access: "none"

Les sections ci-dessous expliquent chaque élément en détail.


<SchemaGrant>

<SchemaGrant> définit l’accès par défaut à l’ensemble du schema. Son attribut access peut être :

ValeurSignification
allLe rôle peut voir tous les cubes et dimensions du schema.
all_dimensionsLe rôle peut voir toutes les dimensions mais a toujours besoin d’entrées <CubeGrant> explicites pour accéder aux données d’un cube.
noneLe rôle ne peut rien voir sauf autorisation explicite.

Dans l’exemple ci-dessus, access="none" signifie que l’utilisateur ne peut parcourir que le cube « Sales », car c’est le seul explicitement autorisé.


<CubeGrant>

<CubeGrant> contrôle l’accès à un cube spécifique. Son attribut access peut être :

ValeurSignification
allAccès complet au cube et à toutes ses dimensions et hiérarchies.
customL’accès est défini par les éléments enfants <DimensionGrant> et <HierarchyGrant>.
noneLe cube est masqué pour le rôle.

<DimensionGrant>

<DimensionGrant> contrôle l’accès à toute une dimension au sein d’un cube. Son attribut access peut être :

ValeurSignification
allToutes les hiérarchies enfants de cette dimension sont accessibles.
customPas d’accès intrinsèque aux hiérarchies enfants — chaque hiérarchie doit être autorisée séparément avec <HierarchyGrant>.
noneLa dimension est masquée.

L’attribut dimension prend le nom unique MDX de la dimension (par exemple "[Measures]" ou "[Store]").


<HierarchyGrant>

<HierarchyGrant> contrôle l’accès à une hiérarchie, contraignant facultativement les niveaux et membres visibles.

AttributRequisDescription
hierarchyouiNom unique MDX de la hiérarchie, par ex. "[Store]".
accessoui"all", "custom" ou "none".
topLevelnonNom unique MDX du niveau visible le plus haut. Les membres au-dessus de ce niveau sont masqués.
bottomLevelnonNom unique MDX du niveau visible le plus bas. Les membres en dessous de ce niveau sont masqués.
rollupPolicynonComment calculer les totaux lorsque certains enfants sont masqués. Voir Politique de roll-up.

Valeurs de access

ValeurSignification
allChaque membre est visible.
noneLa hiérarchie est masquée pour le rôle.
customLa visibilité est contrôlée par topLevel, bottomLevel et/ou les enfants <MemberGrant>.

<MemberGrant>

<MemberGrant> accorde ou refuse l’accès à un membre spécifique et à tous ses enfants. Vous ne pouvez utiliser <MemberGrant> que lorsque le <HierarchyGrant> englobant a access="custom".

AttributRequisDescription
memberouiNom unique MDX du membre, par ex. "[Store].[USA].[CA]".
accessoui"all" ou "none".

Règles pour les autorisations de membres

Les autorisations de membres interagissent d’une manière spécifique lorsque plusieurs autorisations s’appliquent à la même hiérarchie :

  1. Les membres héritent l’accès de leurs parents. Refuser l’accès à la Californie refuse automatiquement l’accès à San Francisco.
  2. Les autorisations dépendent de l’ordre. Si vous accordez l’accès aux USA, puis refusez l’Oregon, l’Oregon est masqué. Si vous refusez l’Oregon d’abord puis accordez les USA, tout est visible. L’ordre compte.
  3. Un membre est visible si l’un de ses enfants est visible. Si vous refusez les USA mais accordez la Californie, vous verrez les USA et la Californie — mais aucun autre état. Note : les totaux pour les USA sous la politique de roll-up full reflètent toujours tous les états (voir Politique de roll-up). Si un topLevel est défini, seuls les parents au niveau ou en dessous sont affichés.
  4. Les autorisations de membre ne remplacent pas topLevel et bottomLevel. Si topLevel="[Store].[Store State]" est défini et que vous accordez la Californie, vous ne pouvez toujours pas voir le niveau USA.

Exemple commenté

Avec le rôle « California manager » de l’exemple d’ouverture, l’utilisateur peut :

  • Voir la Californie et toutes les villes de Californie sauf Los Angeles.
  • Voir les USA (car la Californie, un enfant visible, rend le parent visible), mais aucun autre pays.
  • Ne pas voir « All Stores » car il se trouve au-dessus du topLevel de Store Country.
  • Ne pas voir les clients en dehors de la bande état-vers-ville (State Province à City), et pas Los Angeles.
  • Ne pas voir du tout la hiérarchie Gender.

Sécurité de lignes par prédicat (<PredicateGrant>)

Les autorisations de membre restreignent quels membres de dimension un rôle peut voir. Parfois, vous devez plutôt restreindre les lignes de fait elles-mêmes par une valeur de colonne qui tracke l’utilisateur appelant — la sécurité de lignes multi-tenant classique, ou l’access_filter de Looker. Pour cela, Saiku ajoute un <PredicateGrant> (une extension Saiku à Mondrian 4, issue #106) : il lie un rôle à un filtre sur une vraie colonne de fait, valuée depuis le paramètre de requête de la connexion.

<Role name="Regional">
<SchemaGrant access="all"/>
<PredicateGrant measureGroup="Sales" column="region"
operator="eq" parameter="region"/>
</Role>

Le backend Calcite injecte le prédicat comme filtre WHERE sur chaque chargement de segment du groupe de mesures nommé, pré-agrégation, afin que les totaux — pas seulement les lignes feuilles — soient correctement restreints, et le résultat par rôle est isolé dans le cache de segments. Un paramètre non lié échoue fermé (zéro ligne), jamais non restreint. operator est eq (égalité) ou in (appartenance).


Politique de roll-up

Une politique de roll-up détermine quelle valeur Mondrian affiche pour un membre parent lorsque le rôle courant ne peut pas voir tous ses enfants.

PolitiqueSignification
fullLe total parent inclut tous les enfants, visibles ou non. C’est le défaut.
partialLe total parent n’inclut que les enfants accessibles.
hiddenSi un enfant est inaccessible, le total parent est supprimé.

Exemple : effet de chaque politique

Supposons qu’un rôle puisse voir [USA].[CA] et [USA].[OR] mais pas [USA].[WA], et exécute :

SELECT {[Measures].[Unit Sales]} ON COLUMNS,
{[Store].[USA], [Store].[USA].Children} ON ROWS
FROM [Sales]

Full (par défaut) — le total [USA] inclut les 124 366 unités de Washington :

MembreUnit Sales
[USA]266 773
[USA].[CA]74 748
[USA].[OR]67 659

Partial — le total [USA] ne reflète que CA et OR :

MembreUnit Sales
[USA]142 407
[USA].[CA]74 748
[USA].[OR]67 659

Hidden — le total [USA] est supprimé car au moins un enfant est inaccessible :

MembreUnit Sales
[USA]
[USA].[CA]74 748
[USA].[OR]67 659

Spécifier la politique de roll-up

L’attribut rollupPolicy se trouve sur <HierarchyGrant>. Vous pouvez appliquer des politiques différentes à différentes hiérarchies dans le même rôle :

- name: "South Pacific manager"
schema_grant:
access: "none"
cubes:
- cube: "Sales"
access: "all"
hierarchies:
- hierarchy: "[Store]"
access: "custom"
top_level: "[Store].[Store Country]"
rollup_policy: "partial"
members:
- member: "[Store].[USA].[CA]"
access: "all"
- member: "[Store].[USA].[CA].[Los Angeles]"
access: "none"
- hierarchy: "[Customers]"
access: "custom"
top_level: "[Customers].[State Province]"
bottom_level: "[Customers].[City]"
rollup_policy: "full"
members:
- member: "[Customers].[USA].[CA]"
access: "all"
- member: "[Customers].[USA].[CA].[Los Angeles]"
access: "none"
- hierarchy: "[Gender]"
access: "none"

Rôles d’union

Un rôle d’union combine les privilèges de deux ou plusieurs rôles existants. Le résultat a l’accès le moins restrictif sur tous ses rôles constituants : le rôle d’union peut voir n’importe quel objet de schema qu’au moins un rôle constituant peut voir, et sa politique de roll-up pour une hiérarchie donnée est la politique la moins restrictive parmi tous les constituants.

<Role name="Coastal manager">
<Union>
<RoleUsage roleName="California manager"/>
<RoleUsage roleName="Eastern sales manager"/>
</Union>
</Role>

Les rôles constituants doivent être déclarés plus tôt dans le fichier de schema. Ce peuvent être des rôles ordinaires, d’autres rôles d’union ou des rôles personnalisés basés sur des classes. Le rôle d’union « Coastal manager » peut voir tout membre accessible à l’un ou l’autre constituant, et peut également voir les cellules à l’intersection de membres qu’un seul rôle peut voir.


Définir le rôle d’une connexion

Un rôle prend effet lorsqu’il est associé à une connexion. Par défaut, les connexions ont un rôle non restreint qui peut voir tous les cubes du schema. Il y a deux manières d’activer un rôle spécifique :

Dans la chaîne de connexion

Incluez le mot-clé Role dans la chaîne de connexion Mondrian. Saiku Cloud le définit au nom de vos utilisateurs en fonction de la configuration de votre tenant :

Provider=mondrian; Role="California manager";
Jdbc=jdbc:postgresql://host/db; JdbcUser=user; JdbcPassword=pw;
Catalog=/WEB-INF/MySchema.mondrian.xml

Pour activer plusieurs rôles à la fois (créant une union ad-hoc), séparez les noms par des virgules. Si un nom de rôle contient lui-même une virgule, échappez-la par une double virgule.

Programmatiquement

Si vous embarquez Mondrian directement, appelez Connection.setRole(Role) après avoir ouvert une connexion, ou recherchez un rôle nommé avec Schema.lookupRole(String).


Rôle par défaut

Vous pouvez marquer un rôle comme défaut dans votre schema à l’aide de l’attribut defaultRole sur <Schema>. Toute connexion qui ne spécifie pas explicitement un rôle utilisera ce défaut :

<Schema name="FoodMart" defaultRole="California manager">
...
</Schema>

Rôles dans les schemas YAML

Si vous créez votre schema au format YAML, les rôles sont déclarés sous la clé de niveau supérieur roles. Chaque entrée mappe à un élément <Role>. Voir la référence de schema YAML pour la syntaxe complète roles, y compris les clés schema_grant, cubes, hierarchies, members, rollup_policy, top_level et bottom_level.

Un exemple rapide :

roles:
- name: "California manager"
schema_grant:
access: "none"
cubes:
- cube: "Sales"
access: "all"
hierarchies:
- hierarchy: "[Store].[Stores]"
access: "custom"
top_level: "[Store].[Stores].[Store Country]"
members:
- member: "[Store].[Stores].[USA].[CA]"
access: "all"
- member: "[Store].[Stores].[USA].[CA].[Los Angeles]"
access: "none"
- name: "No HR Cube"
schema_grant:
access: "all"
cubes:
- cube: "HR"
access: "none"

Adapté du guide de schema du projet Mondrian (EPL v1.0).