Zum Inhalt springen

Zugriffskontrolle und Rollen

Das Zugriffskontrollmodell von Mondrian lässt Sie Ihr Schema in Rollen aufteilen. Eine Rolle ist eine benannte Menge von Grants und Denials, die das gesamte Schema abdeckt — von welchen Cubes sichtbar sind bis hinunter zu welchen einzelnen Membern ein Benutzer sehen darf. Sie definieren Rollen direkt in Ihrer Schema-Datei, und Saiku Cloud wendet sie an, wenn es eine Verbindung im Namen eines Benutzers aufbaut.

Eine Rolle definieren

<Role>-Elemente sind direkte Kinder von <Schema>, platziert nach dem letzten <Cube>. Hier ein vollständiges Beispiel:

- 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"

Die Abschnitte unten erklären jedes Element im Detail.


<SchemaGrant>

<SchemaGrant> setzt den Standardzugriff auf das gesamte Schema. Sein access-Attribut kann sein:

WertBedeutung
allDie Rolle kann jeden Cube und jede Dimension im Schema sehen.
all_dimensionsDie Rolle kann alle Dimensionen sehen, benötigt aber weiterhin explizite <CubeGrant>-Einträge, um auf die Daten eines Cubes zuzugreifen.
noneDie Rolle kann nichts sehen, es sei denn, es wird explizit gewährt.

Im obigen Beispiel bedeutet access="none", dass der Benutzer nur den „Sales”-Cube durchsuchen kann, weil er der einzige ist, der explizit gewährt wird.


<CubeGrant>

<CubeGrant> steuert den Zugriff auf einen bestimmten Cube. Sein access-Attribut kann sein:

WertBedeutung
allVoller Zugriff auf den Cube und alle seine Dimensionen und Hierarchien.
customDer Zugriff wird durch Kind-<DimensionGrant>- und <HierarchyGrant>-Elemente definiert.
noneDer Cube ist für die Rolle versteckt.

<DimensionGrant>

<DimensionGrant> steuert den Zugriff auf eine ganze Dimension innerhalb eines Cubes. Sein access-Attribut kann sein:

WertBedeutung
allAlle Kind-Hierarchien dieser Dimension sind zugänglich.
customKein inhärenter Zugriff auf Kind-Hierarchien — jede Hierarchie muss separat über <HierarchyGrant> gewährt werden.
noneDie Dimension ist versteckt.

Das dimension-Attribut nimmt den eindeutigen MDX-Namen der Dimension (zum Beispiel "[Measures]" oder "[Store]").


<HierarchyGrant>

<HierarchyGrant> steuert den Zugriff auf eine Hierarchie und schränkt optional die sichtbaren Levels und Member ein.

AttributErforderlichBeschreibung
hierarchyjaEindeutiger MDX-Name der Hierarchie, z. B. "[Store]".
accessja"all", "custom" oder "none".
topLevelneinEindeutiger MDX-Name des höchsten sichtbaren Levels. Member über diesem Level sind versteckt.
bottomLevelneinEindeutiger MDX-Name des niedrigsten sichtbaren Levels. Member unter diesem Level sind versteckt.
rollupPolicyneinWie Summen berechnet werden, wenn einige Kinder versteckt sind. Siehe Rollup-Policy.

access-Werte

WertBedeutung
allJeder Member ist sichtbar.
noneDie Hierarchie ist für die Rolle versteckt.
customDie Sichtbarkeit wird durch topLevel, bottomLevel und/oder <MemberGrant>-Kinder gesteuert.

<MemberGrant>

<MemberGrant> gewährt oder verweigert den Zugriff auf einen bestimmten Member und alle seine Kinder. Sie können <MemberGrant> nur verwenden, wenn das umschließende <HierarchyGrant> access="custom" hat.

AttributErforderlichBeschreibung
memberjaEindeutiger MDX-Name des Members, z. B. "[Store].[USA].[CA]".
accessja"all" oder "none".

Regeln für Member-Grants

Member-Grants interagieren auf eine bestimmte Weise, wenn mehrere Grants auf dieselbe Hierarchie angewendet werden:

  1. Member erben den Zugriff von ihren Eltern. Den Zugriff auf California zu verweigern, verweigert automatisch den Zugriff auf San Francisco.
  2. Grants sind reihenfolgenabhängig. Wenn Sie Zugriff auf USA gewähren und dann Oregon verweigern, ist Oregon versteckt. Wenn Sie zuerst Oregon verweigern und dann USA gewähren, ist alles sichtbar. Die Reihenfolge zählt.
  3. Ein Member ist sichtbar, wenn eines seiner Kinder sichtbar ist. Wenn Sie USA verweigern, aber California gewähren, sehen Sie USA und California — aber keine anderen Staaten. Hinweis: Summen für USA unter der full-Rollup-Policy spiegeln weiterhin alle Staaten wider (siehe Rollup-Policy). Wenn ein topLevel gesetzt ist, werden nur Eltern auf oder unter diesem Level gezeigt.
  4. Member-Grants überschreiben nicht topLevel und bottomLevel. Wenn topLevel="[Store].[Store State]" gesetzt ist und Sie California gewähren, können Sie immer noch nicht das USA-Level sehen.

Beispieldurchgang

Mit der „California manager”-Rolle aus dem Eröffnungsbeispiel kann der Benutzer:

  • California und alle Städte in California außer Los Angeles sehen.
  • USA sehen (weil California, ein sichtbares Kind, den Eltern sichtbar macht), aber keine anderen Länder.
  • „All Stores” nicht sehen, weil es über dem topLevel von Store Country liegt.
  • Kunden außerhalb des State-to-City-Bandes (State Province bis City) nicht sehen, und nicht Los Angeles.
  • Die Gender-Hierarchie überhaupt nicht sehen.

Predicate-basierte Zeilensicherheit (<PredicateGrant>)

Member-Grants schränken ein, welche Dimensions-Member eine Rolle sehen kann. Manchmal müssen Sie stattdessen die Faktenzeilen selbst durch einen Spaltenwert einschränken, der den anfragenden Benutzer verfolgt — klassische Multi-Tenant-Row-Level-Security oder Lookers access_filter. Dafür fügt Saiku ein <PredicateGrant> hinzu (eine Saiku-Erweiterung zu Mondrian 4, Issue #106): Es bindet eine Rolle an einen Filter auf einer echten Faktenspalte, bewertet vom Query-Parameter der Verbindung.

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

Das Calcite-Backend injiziert das Predicate als WHERE-Filter auf jedem Segment-Load der benannten Measure-Gruppe, vor-Aggregation, sodass Summen — nicht nur Blattzeilen — korrekt eingeschränkt sind, und das Ergebnis pro Rolle ist im Segment-Cache isoliert. Ein ungebundener Parameter schlägt geschlossen fehl (null Zeilen), niemals uneingeschränkt. operator ist eq (Gleichheit) oder in (Mitgliedschaft).


Rollup-Policy {#rollup-policy}

Eine Rollup-Policy bestimmt, welchen Wert Mondrian für einen Eltern-Member anzeigt, wenn die aktuelle Rolle nicht alle seine Kinder sehen kann.

PolicyBedeutung
fullDie Eltern-Summe enthält alle Kinder, sichtbar oder nicht. Dies ist der Standard.
partialDie Eltern-Summe enthält nur die zugänglichen Kinder.
hiddenWenn ein Kind unzugänglich ist, wird die Eltern-Summe unterdrückt.

Beispiel: Wirkung jeder Policy

Angenommen, eine Rolle kann [USA].[CA] und [USA].[OR] sehen, aber nicht [USA].[WA], und führt aus:

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

Full (Standard)[USA]-Summe enthält Washingtons 124.366 Stück:

MemberUnit Sales
[USA]266.773
[USA].[CA]74.748
[USA].[OR]67.659

Partial[USA]-Summe spiegelt nur CA und OR wider:

MemberUnit Sales
[USA]142.407
[USA].[CA]74.748
[USA].[OR]67.659

Hidden[USA]-Summe wird unterdrückt, weil mindestens ein Kind unzugänglich ist:

MemberUnit Sales
[USA]
[USA].[CA]74.748
[USA].[OR]67.659

Die Rollup-Policy angeben

Das rollupPolicy-Attribut sitzt auf <HierarchyGrant>. Sie können unterschiedliche Policies auf unterschiedliche Hierarchien in derselben Rolle anwenden:

- 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"

Union-Rollen

Eine Union-Rolle kombiniert die Privilegien von zwei oder mehr bestehenden Rollen. Das Ergebnis hat den am wenigsten restriktiven Zugriff über alle Bestandteile-Rollen: Die Union-Rolle kann jedes Schema-Objekt sehen, das mindestens eine Bestandteile-Rolle sehen kann, und ihre Rollup-Policy für eine gegebene Hierarchie ist die am wenigsten restriktive Policy unter allen Bestandteilen.

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

Die Bestandteile-Rollen müssen früher in der Schema-Datei deklariert werden. Sie können reguläre Rollen, andere Union-Rollen oder benutzerdefinierte klassengestützte Rollen sein. Die „Coastal manager”-Union-Rolle kann jeden Member sehen, der für eine der beiden Bestandteile-Rollen zugänglich ist, und kann auch Zellen am Schnittpunkt von Membern sehen, die nur eine Rolle sehen kann.


Die Rolle einer Verbindung setzen

Eine Rolle wird wirksam, wenn sie mit einer Verbindung verknüpft ist. Standardmäßig haben Verbindungen eine uneingeschränkte Rolle, die jeden Cube im Schema sehen kann. Es gibt zwei Wege, eine bestimmte Rolle zu aktivieren:

Im Connect-String

Schließen Sie das Role-Keyword in den Mondrian-Connect-String ein. Saiku Cloud setzt dies im Namen Ihrer Benutzer basierend auf Ihrer Tenant-Konfiguration:

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

Um mehrere Rollen gleichzeitig zu aktivieren (eine Ad-hoc-Union zu erstellen), trennen Sie die Namen durch Kommas. Wenn ein Rollenname selbst ein Komma enthält, escapen Sie ihn mit einem doppelten Komma.

Programmatisch

Wenn Sie Mondrian direkt einbetten, rufen Sie Connection.setRole(Role) nach dem Öffnen einer Verbindung auf oder schlagen Sie eine benannte Rolle mit Schema.lookupRole(String) nach.


Standardrolle

Sie können eine Rolle als Standard in Ihrem Schema mit dem defaultRole-Attribut auf <Schema> markieren. Jede Verbindung, die nicht explizit eine Rolle angibt, verwendet diesen Standard:

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

Rollen in YAML-Schemas

Wenn Sie Ihr Schema im YAML-Format erstellen, werden Rollen unter dem Top-Level-roles-Schlüssel deklariert. Jeder Eintrag entspricht einem <Role>-Element. Siehe die YAML-Schema-Referenz für die vollständige roles-Syntax, einschließlich schema_grant-, cubes-, hierarchies-, members-, rollup_policy-, top_level- und bottom_level-Schlüsseln.

Ein kurzes Beispiel:

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"

Übernommen aus dem Mondrian-Projekt-Schema-Guide (EPL v1.0).