Best practices voor RLS voor databronnen en werkmappen

Met beveiliging op rijniveau (RLS - Row-level security) in Tableau beperkt u de rijen met data die een bepaalde gebruiker in een werkmap kan zien. Dit verschilt van Tableau-machtigingen, waarmee de toegang tot inhoud en functionaliteit wordt beheerd. Met machtigingen wordt bijvoorbeeld bepaald of een gebruiker een werkmap mag bewerken of er opmerkingen bij mag plaatsen. Beveiliging op rijniveau zorgt ervoor dat twee gebruikers die hetzelfde dashboard bekijken, alleen de data kunnen zien die de desbetreffende gebruiker mag zien.

Er zijn verschillende manieren om RLS in Tableau te implementeren. U kunt RLS bijvoorbeeld instellen op het niveau van de databron of werkmap, of u kunt RLS instellen op het verbindingsniveau met behulp van een virtuele verbinding met databeleid (vereist Databeheer). Zie Overzicht van beveiligingsopties op rijniveau in Tableau voor meer informatie over alternatieven.

Opmerking: dit onderwerp richt zich op best practices voor RLS voor databronnen en werkmappen. Voor meer diepgaande voorbeelden van de concepten die in dit onderwerp worden beschreven, verwijzen wij u naar het whitepaper Aanbevolen procedures voor beveiliging op rijniveau met rechtentabellen(Link wordt in een nieuw venster geopend) of Hoe u uw database instelt voor beveiliging op rijniveau in Tableau(Link wordt in een nieuw venster geopend) op het blog Tableau and Behold.

RLS-workflow

Voor live verbindingen en extracten met meerdere tabellen is de basis-RLS-workflow als volgt:

  1. De gebruiker wordt geïdentificeerd door in te loggen bij Tableau Server of Tableau Cloud
    • Hiervoor is een aparte gebruikersnaam per gebruiker en veilige, eenmalige aanmelding (SSO) nodig
    • Active Directory, LDAP of de Tableau REST API kunnen worden gebruikt om gebruikersnamen te synchroniseren en machtigingen in te stellen
  2. De set datarechten voor de gebruiker wordt opgehaald uit alle mogelijke datarechten
    • Hiervoor is een datastructuur nodig die rechten aan de Tableau-gebruikersnaam kan koppelen
  3. De data worden gefilterd op basis van de rechten voor die gebruiker
    • Hiervoor is het vaak nodig om gebruikersfuncties in een berekend veld te gebruiken
  4. De gepubliceerde, gefilterde data worden gebruikt om inhoud samen te stellen
    • Door een gepubliceerde (in plaats van een ingesloten) databron te gebruiken met een databronfilter, wordt ervoor gezorgd dat RLS niet kan worden gewijzigd door de werkmap te downloaden of via internet te bewerken.

De manier waarop de joins, berekende velden en filters worden ingesteld, hangt af van de structuur van de data en de manier waarop gebruikers worden beheerd.

Rechtentabellen

Elke unieke combinatie van kenmerken waarop de data kunnen worden gefilterd, is een recht. Meestal zijn er aparte tabellen waarin de rechten zelf worden aangegeven en waarin deze rechten worden toegewezen aan gebruikers of gebruikersrollen. Denormaliseren wordt aanbevolen vanuit een het perspectief van de prestaties, omdat joins dure bewerkingen zijn.

De rechtenweergave, bestaande uit de rechten die zijn toegewezen aan gebruikers of rollen, wordt gekoppeld aan de data. Vervolgens wordt een op de gebruiker gebaseerd databronfilter toegepast, dat fungeert als een WHERE-clausule die alleen de rechten (en dus de juiste datarijen) voor de relevante gebruiker ophaalt. (Query-optimalisatie moet ervoor zorgen dat het filteren plaatsvindt voordat de query wordt samengevoegd en verwerkt, om duplicatie van data tot een minimum te beperken.) Zie Prestaties en verwerkingsvolgorde van bewerkingen voor meer informatie.

Modellen voor rechtentabellen

Er zijn over het algemeen twee modellen voor het weergeven van rechten:

Volledig in kaart brengen tot op het diepste granulariteitsniveau

  • Rechten worden voor elke kolom volledig gedefinieerd.
  • Er is één rij in de toewijzingstabel voor elk mogelijk recht dat de gebruiker heeft.
  • Dit model vereist minder join-clausules.

Spaarzame rechten

  • Rechten worden gedefinieerd voor elk hiërarchieniveau, waarbij NULL wordt gebruikt om de status 'alles' weer te geven.
  • Er is één rij in de toewijzingstabel voor een bepaald niveau in de rechtenhiërarchie. Hierdoor wordt het aantal rechtenrijen voor gebruikers op hogere niveaus in een hiërarchie aanzienlijk verminderd.
  • Voor dit model zijn complexere joins en filters nodig.

Gebruikers en rollen

Combinaties van rechten worden doorgaans weergegeven als rollen, die vervolgens aan gebruikers worden gekoppeld in een veel-op-veel-toewijzingstabel. Hierdoor kunt u de rol van een gebruiker eenvoudig wijzigen of verwijderen, terwijl u toch een overzicht van de rol en de bijbehorende rechten bijhoudt.

U kunt er ook voor kiezen om een veel-op-veel-toewijzingstabel te maken, waarbij gebruikers rechtstreeks aan rechten worden toegewezen in plaats van dat u via een roltabel lid wordt. Hierdoor moeten de waarden rechtstreekser in de tabel worden beheerd, maar is er geen join nodig.

Opmerking: de gebruikerswaarden die aan een rol of recht zijn gekoppeld, moeten overeenkomen met de gebruikersnaam of volledige naam op de Tableau-site om de gebruikersfuncties in Tableau Desktop te kunnen benutten.

Joins

Ongeacht het model dat wordt gebruikt om de rechten weer te geven, is het raadzaam om alle rechten en toewijzingstabellen samen te voegen tot één gedenormaliseerde rechtenweergave. Hoewel dit in eerste instantie een ‘opgeblazen’ (met veel duplicaten) versie van de rechten veroorzaakt, zal het databronfilter op de gebruiker dit weer terugbrengen. Deze weergave is ook handig als u een fragment wilt gebruiken.

De methode met de diepste granulariteit kan een prestatievoordeel opleveren wanneer alles hiërarchisch is: u hoeft slechts één join uit te voeren op het diepste niveau van de hiërarchie. Dit werkt alleen als alle kenmerken op het laagste niveau verschillend zijn. Als er een kans is op duplicatie (bijvoorbeeld een centrale subregio in meer dan één regio), dan moet u alle kolommen samenvoegen om het effect van een afzonderlijke sleutelwaarde te bereiken.

De werkelijke details en de prestatiekenmerken zijn afhankelijk van het datasysteem en hiervoor is testen vereist. Het gebruik van één enkele sleutel kan bijvoorbeeld de prestaties potentieel verbeteren, omdat de join dan maar op één kolom wordt uitgevoerd. Als echter alle kolommen juist worden geïndexeerd, kunnen de prestaties gelijk blijven als andere factoren in overweging worden genomen.

Beveiliging op rijniveau implementeren

Diepste granulariteit

Nadat de gedenormaliseerde weergave van toegewezen rechten is gemaakt, wordt er een binnenste join ingesteld tussen de weergave en de data in het dialoogvenster Dataverbinding van Tableau. De data kunnen in een traditioneel sterschema blijven staan. Als alternatief kunnen de dimensie- en feitentabellen samen in twee weergaven worden weergegeven. Bij extracties met meerdere tabellen worden extractietabellen gemaakt die overeenkomen met de joins. Door twee weergaven te maken, wordt het uiteindelijke extract eenvoudiger. De SQL volgt dit basispatroon:

SELECT * 
FROM data d INNER JOIN entitlements e ON
d.attribute_a = e.attribute_a AND 
d.attribute_b = e.attribute_b AND ... 
WHERE e.username = USERNAME()

Spaarzame rechten

Als uw rechten meer lijken op het model met spaarzame rechten, dan is de aangepaste SQL om de data aan de rechten te koppelen iets complexer vanwege de NULL-waarden. Conceptueel ziet het er dan als volgt uit: 

SELECT *
FROM data d 
INNER JOIN entitlements e ON
(e.region_id = d.region_id OR ISNULL(e.region_id) AND
(e.sub_region_id = d.sub_region_id OR ISNULL(e.sub_region_id) AND
(e.country_id = d.country_id OR ISNULL(e.country_id)

Dit kan worden gedaan met een cross join en extra filters in Tableau Desktop, zonder dat u aangepaste SQL hoeft te gebruiken. Maak aan beide kanten van het dialoogvenster Join een join-berekening die eenvoudigweg bestaat uit het gehele getal 1 en stel ze aan elkaar gelijk. Hiermee worden alle rijen uit de datatabel gekoppeld aan alle rijen in de rechtentabel.

Dan hebt u een berekening (of individuele berekeningen) nodig om rekening te houden met de niveaus in de hiërarchie. U kunt bijvoorbeeld meerdere berekeningen hebben die deze indeling volgen: [region_id] = [region_id (Entitlements View)] OR ISNULL([region_id (Entitlements View)]

Of u kunt een gecombineerde berekening voor alle niveaus in één maken:

([region_id] = [region_id (Entitlements View)] OR ISNULL([region_id (Entitlements View)])
AND
([sub_region_id] = [sub_region_id (Entitlements View)] OR ISNULL([sub_region_id (Entitlements View)])
AND
([country_id] = [country_id (Entitlements View)] OR ISNULL([country_id (Entitlements View)])

De ISNULL-functie koppelt elke rechtenkolom aan alle items in de andere kolom. Zoals altijd bij RLS moeten deze berekeningen als databronfilters worden toegevoegd.

Databronfilter

Voor beide benaderingen geldt dat zodra de rechten juist zijn gekoppeld aan de data, er een filter moet worden ingesteld om de data voor een specifieke gebruiker te beperken. Er moet met een gebruikersfunctie een berekend veld worden gemaakt. Bijvoorbeeld een eenvoudige Booleaanse vergelijking om te bepalen of de gebruiker die in het veld Gebruikersnaam staat vermeld, dezelfde is als de gebruikersnaam van degene die is ingelogd op de Tableau-site: [Username] = USERNAME()

Deze berekening moet worden gebruikt als een databronfilter (met TRUE geselecteerd).

Als de databron is ingesloten en een gebruiker machtigingen heeft om de werkmap op het web te bewerken of te downloaden, bestaat de RLS niet, omdat de filters die deze afdwingen, eenvoudig kunnen worden verwijderd. De Tableau-databron moet afzonderlijk worden gepubliceerd en niet ingesloten blijven in de werkmap.

Alle toegang met de diepste granulariteit

Er is ook een veelvoorkomend scenario waarin er binnen de organisatie twee toegangsniveaus zijn: mensen die alles kunnen zien (‘alle toegang’) of mensen met een redelijkerwijs definieerbare subset van rechten. Dit komt het vaakst voor bij ingesloten toepassingen: de organisatie die de data host, kan alles zien, maar elke client kan alleen zijn eigen data zien. In dit geval hebt u een manier nodig om de volledige data voor de 'alle toegang'-gebruikers te retourneren, terwijl de diepste granulariteitsjoins voor alle andere gebruikers behouden blijven.

Voor deze techniek gebruikt u Tableau-groepen om met behulp van een berekening in de samenvoegvoorwaarde een negeerfunctie in te stellen.

  1. Maak een groep voor gebruikers die alle data moeten kunnen zien (hier 'All Access' genoemd) 
  2. Maak vanuit het feitenoverzicht een join links met twee join-voorwaarden
    • De eerste join-voorwaarde moet zich bevinden in de kolom die het diepste granulariteitsniveau vertegenwoordigt
    • De tweede samenvoegingsvoorwaarde moet bestaan uit twee berekeningen:
      • Voer aan de linkerkant (het feitenoverzicht) voor de berekening het volgende in: True
      • Aan de rechterkant (het rechtenoverzicht) zou de berekening er als volgt uit moeten zien: IF ISMEMBEROF('All Access') THEN False ELSE True END
  3. Maak op een werkblad een berekening die als volgt is gestructureerd: [Username] = USERNAME() OR ISMEMBEROF(['All Access'] ([Entitlements View)])
  4. Maak een databronfilter op de gebruikersnaamberekening

Als een gebruiker lid is van de groep All Access, wordt de join een join links op True = False. Dit betekent dat er helemaal geen overeenkomsten zijn in de rechtenweergave, waardoor de volledige feitenweergave wordt geretourneerd met NULL's voor de kolommen uit de rechtenweergave (geen duplicatie). In het geval dat de gebruiker geen deel uitmaakt van de groep All Access, verandert de voorwaarde voor de True = True-join niet en functioneert de join zoals verwacht.

De gebruikersberekening die als databronfilter wordt gebruikt, geldt voor alle rijen wanneer het negeren van de groep actief is, of filtert alleen tot de diepste granulariteit van de gebruiker in de hiërarchie.

Prestaties en verwerkingsvolgorde van bewerkingen

Wanneer er een visualisatie wordt bekeken in Tableau Desktop, Tableau Server of Tableau Cloud, stuurt Tableau een geoptimaliseerde query naar het RDBMS, dat de query vervolgens verwerkt en de resultaten terugstuurt naar Tableau om de visualisatie met de resulterende data weer te geven. De volgorde waarin koppelingen, berekeningen en filters worden uitgevoerd, is afhankelijk van de queryoptimizer en de manier waarop de query wordt uitgevoerd.

Live verbindingen

Wanneer u een live verbinding met een databron in Tableau gebruikt, zijn de prestaties van het uitvoeren van de query afhankelijk van de queryoptimizer die de binnenkomende SQL omzet naar een efficiënt plan om de data op te halen.

Er zijn twee manieren waarop de query kan worden verwerkt:

  1. Filter de rechtenrijen op de gebruiker en voeg ze vervolgens toe aan de feitentabel
  2. Voeg de rechten toe aan de feitentabel en filter vervolgens op de rijen van de gebruiker

In een ideale situatie zorgt de queryoptimizer ervoor dat de database de query verwerkt door te filteren en vervolgens samen te voegen. Als een gebruiker recht heeft op alles, betekent dit dat het maximale aantal verwerkte rijen gelijk is aan het aantal rijen in de datatabel.

Als de database de query verwerkt door joining en vervolgens filteren, kan er sprake zijn van duplicatie van data. Het maximale aantal verwerkte rijen is het aantal gebruikers dat gerechtigd is om die specifieke rij te bekijken, vermenigvuldigd met elke rij in de datatabel.

Het zal duidelijk zijn als dit tweede scenario zich voordoet, het lang duurt tot uw query's zijn afgerond, u foutmeldingen krijgt of er sprake is van prestatieproblemen in de database. Uw totale datavolume neemt exponentieel toe, wat kan leiden tot buitensporige systeembelasting op de backend.

Extracten

Wanneer de databron in Tableau een live verbinding is, stuurt Tableau elke query die nodig is om een specifieke visualisatie of dashboard weer te geven naar de RDBMS. Wanneer de databron een extract is, vindt het opvragen van data uit de onderliggende databron alleen plaats bij het maken en vernieuwen van het extract. Alle afzonderlijke query's voor visualisaties worden door de extract-engine beantwoord vanuit het extractbestand.

Hetzelfde probleem met de volgorde van bewerkingen doet zich voor bij het maken van extracten van afzonderlijke tabellen. De ‘explosie’ zal echter zowel in de onderliggende databron als in het resulterende extract zelf plaatsvinden.

Overwegingen bij extracten

Vanaf Tableau 2018.3 kan de data-engine een multi-tabel extract maken en kan RLS worden geïmplementeerd zoals hierboven beschreven. Door meerdere tabelextracten te gebruiken, wordt de tijd die nodig is om een extract met veel-op-veel-relaties te genereren verkort doordat de join niet wordt gemaakt.

Het extract moet worden opgebouwd met een dataobject en een rechtenobject. Dit is de eenvoudigste methode om data in het extract op te slaan en levert de beste prestaties op.

  • Het dataobject is de tabel, weergave of aangepaste SQL-query die de gedenormaliseerde combinatie van de feiten- en noodzakelijke dimensietabellen vertegenwoordigt
  • He rechtenobject is een gedenormaliseerde tabel, weergave of aangepaste SQL-query met de rechten die nodig zijn om de data op het meest gedetailleerde niveau te filteren. Hiervoor is het volgende vereist:
    • Een kolom voor gebruikersnamen die exact overeenkomen met de gebruikersnamen in Tableau Server of Tableau Cloud
    • Een rij voor elk van de meest gedetailleerde rechten op het dataobject

Deze indeling staat hierboven weergegeven met de diepste granulariteitsmethode. Voor extracten uit meerdere tabellen wordt dezelfde methode gevolgd, maar met de kanttekening dat er slechts twee dataobjecten worden samengevoegd en dat eventuele veldspecifieke filtering al binnen het object is toegepast.

Omdat extractiefilters voor meerdere tabelextracties zijn uitgeschakeld, kunt u filteren in de weergaven of tabellen waarmee u verbinding maakt in de databron, of de filters definiëren in aangepaste SQL-objecten in het Tableau-dialoogvenster Dataverbinding.

Opmerking: net als bij live verbindingen bestaat RLS niet als de databron is ingesloten en een gebruiker machtigingen heeft om de werkmap te bewerken of te downloaden. De filters die RLS afdwingen, kunnen namelijk eenvoudig worden verwijderd. Het extract moet apart worden gepubliceerd en mag niet in de werkmap ingesloten blijven.

Extracten uit één tabel

De volgende methode wordt alleen aanbevolen bij gebruik van een versie van Tableau vóór 2018.3: extracten uit meerdere tabellen hebben de voorkeur als deze beschikbaar zijn.

Bij extracten uit één tabel worden alle joins die u maakt bij het samenstellen van de Tableau-databron gemaakt en wordt alles via één query als één tabel opgeslagen. De resultaten hiervan worden in het extractbestand in één tabel omgezet. Deze denormalisatie brengt het risico met zich mee dat er enorme dataduplicatie ontstaat, omdat elke rij die aan meer dan één recht of gebruiker is toegewezen, wordt gedupliceerd als gevolg van de veel-op-veelrelatie.

Zo voorkomt u deze duplicatie:

  1. Maak een veld met de naam Beveiligingsgebruikers dat de gebruikersnamen voor dat recht bevat
    • bijvoorbeeld de waarde: “bhowell|mosterheld|rdugger”
  2. Gebruik de functie CONTAINS() binnen Tableau om individuele gebruikers juist te identificeren
    • Bijvoorbeeld: CONTAINS([Security Users Field], USERNAME())

Deze methode kent uiteraard enkele kanttekeningen. U moet hiervoor van uw rechten in rijen naar één kolom gaan die juist is gescheiden met behulp van SQL. Die kolom kan slechts een beperkt aantal tekens bevatten. Gedeeltelijke overeenkomsten kunnen problemen opleveren en u moet scheidingstekens gebruiken die nooit geldig zijn in de ID's zelf. Hoewel deze aanpak binnen de Tableau-data-engine goed presteert, zal de aanpak voor de meeste databases erg traag zijn als tekenreeksberekening. Hierdoor is het beperkt mogelijk om terug te schakelen naar een live verbinding.

U kunt er ook voor kiezen om verschillende extracten per 'rol' of bevoegdheidsniveau te maken, zodat alleen de data die geschikt zijn voor die persoon of dat niveau in het extract worden opgenomen. Hiervoor zijn echter processen nodig die de publicatie van sjablonen binnen Tableau Server op de juiste manier machtigen en benutten, doorgaans via de API's.

Ingebouwde beveiliging op rijniveau gebruiken in een database

Veel databases hebben ingebouwde mechanismen voor RLS. Als uw organisatie al moeite heeft gestoken in het opbouwen van beveiliging op rijniveau in een database, kunt u mogelijk profiteren van uw bestaande RLS. Het is niet per se gemakkelijker of beter om een ingebouwd RLS-model te implementeren dan om het op te bouwen met Tableau in gedachten. Deze technieken worden over het algemeen toegepast wanneer een organisatie al in deze technologieën heeft geïnvesteerd en van die investering wil profiteren. Het belangrijkste voordeel van het gebruik van ingebouwde RLS is dat beheerders hun databeveiligingsbeleid op één plek kunnen implementeren en beheren: in hun databases. Zie Beveiliging op rijniveau in de database voor meer informatie.

Bedankt voor uw feedback.De feedback is verzonden. Dank u wel.