Dynamische Sicherheit in Tabular Cubes

 Oft steht man vor dem Problem, dass man im Tabular Cube die Sicherheit nicht auf Tabellenebene, sondern auf Zeilenebene angeben möchte.
Zudem sollen verschiedene Nutzer nur auf bestimmte Daten innerhalb der Tabelle Zugriff haben.
Wie man dieses Problem im Tabular Cube lösen kann, möchte ich in diesem Beitrag erläutern.

 

Dazu habe ich einen Tabular Cube erstellt. Dieser besteht aus lediglich einer Faktentabelle (FactResellerSales) und einer Dimension (DimSalesTerritory). Als Quelle wird die AdventureWorksDW2012 Datenbank verwendet.

Der Tabular Cube sieht wie folgt aus:

 



Nun legen wir ein Measure an, welches für unsere Testzwecke verwendet wird.
Dies ist der Einfachheit halber eine Summe über den SalesAmount und wird durch folgendes DAX – Statement realisiert:

 

SumOfSalesAmount:=SUM([SalesAmount])

 

Abschließend ergibt sich folgendes Bild:



 

Nun besitzen wir einen einfachen Cube, den wir für unser Sicherheitsbeispiel verwenden können.
Unser Beispiel soll verschiedenen Domänennutzern Zugriff auf die eben erstellte Measure ermöglichen. Dabei wird der Zugriff auf Grundlage des SalesTerritoryKey in der DimSalesTerritory – Dimension beschränkt.
User1 soll lediglich Zugriff auf die Ausprägungen 1,2,3,4 besitzen, während User2 Zugriff auf die Schlüssel 4, 5 und 6 hat.

 

Dazu muss zuerst eine Sicherheitstabelle angelegt werden, welche pro Nutzer (oder Rolle, in die bspw. eine Domänengruppe eingetragen werden kann) alle sichtbaren Elemente enthält.
Aus administrativer Sicht ist die Variante Rollen zu nutzen sicherlich besser. In diesem Blogbeitrag belasse ich es beispielhaft bei konkreten Usern.

 

Die Sicherheitstabelle kann sehr einfach in Excel erstellt werden, indem folgende Tabelle verwendet wird (Die Nutzer sind noch durch Domänennutzer zu ersetzen und sollten mindestens Lesezugriff auf den Tabular Cube haben):

 

User Name Allowed SalesTerritory
DOMAIN\User1 1
DOMAIN\User1 2
DOMAIN\User1 3
DOMAIN\User1 4
DOMAIN\User2 4
DOMAIN\User2 5
DOMAIN\User2 6

 

Den Tabelleninhalt können Sie über Edit à Paste in das Tabular Model kopieren. In dem aufgehenden Wizard geben Sie den Namen (z.B. Security) an und bestätigen mit Ok.


 

 

Nun legen wir noch eine Tabelle an, welche alle User genau einmal enthält und nennen diese bspw. User. Dazu kann diese Tabelle nach Excel kopiert, anschließend modifiziert und abschließend in das Tabular Modell eingefügt werden:

 

User Name
DOMAIN\User1
DOMAIN\User2

 

Nach dem Anlegen der beiden Tabellen sieht das Tabular Modell wie folgt aus.

 

 

Da alle benötigten Tabellen im Modell enthalten sind, werden nun die Relationen definiert.
Dazu geht man in die Diagramm Sicht (zu finden in der unteren, rechten Ecke). Nun wird der User Name aus der User – Tabelle auf den User Name in der Security – Tabelle gezogen. Somit wird eine 1:n – Beziehung zwischen der User – und der Security – Tabelle gezogen.
 
Anschließend ziehen wir den
SalesTerritoryKey aus der DimSalesTerritory – Tabelle auf die Allowed SalesTerritory der Security – Tabelle und schaffen somit eine weiter 1:n – Beziehung.


 

Die beiden Sicherheitstabellen sollten versteckt werden, um das Darstellen dieser in bspw. Excel zu vermeiden. Dazu werden die User – und die Security – Tabelle ausgewählt und mittels Rechtsklick -> Hide from Client Tools versteckt.

 

Nun werden die eigentlichen Reihenfilter definiert.
Dies geschieht wie folgt:

1.)    Unter Model -> Roles wird eine neue Rolle mit Permissions Read angelegt.

2.)    Im DAX Filter bei der Security – Tabelle wird =False() eingetragen.

3.)    Die User – Tabelle erhält den Ausdruck =[User Name]=USERNAME()

4.)    Die DimSalesTerritory – Tabelle kann wie folgt gefiltert werden:

 

=[SalesTerritoryKey]=CALCULATE(VALUES(‚Security'[Allowed SalesTerritory]), SUMMARIZE(‚Security‘, Security[User Name]), ‚Security'[User Name]=USERNAME()).

 

 
Mittels der SUMMARIZE – Funktion wird eine 1 – Spaltentabelle im Speicher erzeugt, welche nur die unique User enthält. Diese Funktion wird im Kontext des eingeloggten Users berechnet und liefert somit entweder eine Zeile (der momentan eingeloggte User hat Berechtigungen) oder keine Zeile.

Die VALUES – Funktion konstruiert nun eine weitere In-Memory Tabelle, welche entsprechend dem User und der in der Security – Tabelle definierten erlaubten Territorien die zulässigen Zeilen bestimmt.



 

 

Der Vollständigkeit halber sei erwähnt, dass die Umsetzung auch auf anderem Weg erzeugt werden kann.

 

Anstatt den Satz  der erlaubten SalesTerritories zu berechnen, kann auch die Anzahl der ungefilterten Reihen in der Security – Tabelle verwendet werden.
Dazu wird im Measurebereich der Security – Tabelle folgendes Measure definiert:

 

 

Count Security:=COUNTROWS(Security)

 

Dieses wird, wie die Tabelle auch, wieder mittels „Hide from Client Tools“ versteckt.
Die nächsten Schritte sind simultan zu den bereits beschriebenen.
Erzeugen einer neuen Rolle und setzen der ersten beiden Filter für die User- und die Security – Tabelle.
Die DimSalesTerritory – Tabelle erhält nun jedoch folgenden Filter:

 

=CALCULATE(Security[Count Security], Security[User Name]=USERNAME()) > 0

 

Schreibe einen Kommentar