Autorisatie beheren via beveiliging op kolom- en rijniveau
In dit onderwerp wordt uitgelegd hoe u autorisatie kunt beheren via beveiliging op kolom- en rijniveau in Azure Synapse Analytics. We beginnen met het bespreken van beveiliging op kolomniveau in Azure Synapse Analytics en eindigen met beveiliging op rijniveau.
Beveiliging op kolomniveau in Azure Synapse Analytics
Over het algemeen vereenvoudigt beveiliging op kolomniveau een ontwerp en codering voor de beveiliging in uw toepassing. Hiermee kunt u de toegang tot kolommen beperken om gevoelige gegevens te beveiligen. Als u er bijvoorbeeld voor wilt zorgen dat een specifieke gebruiker 'Leo' alleen toegang heeft tot bepaalde kolommen van een tabel omdat hij zich op een specifieke afdeling bevindt. De logica voor Leo alleen voor toegang tot de kolommen die zijn opgegeven voor de afdeling waarin hij werkt, is een logica die zich in de databaselaag bevindt, in plaats van op de gegevenslaag op toepassingsniveau. Als hij toegang moet krijgen tot gegevens uit een willekeurige laag, moet de database de toegangsbeperking toepassen telkens wanneer hij probeert toegang te krijgen tot gegevens uit een andere laag. De reden hiervoor is ervoor te zorgen dat uw beveiliging betrouwbaar en robuust is, omdat we het oppervlak van het algehele beveiligingssysteem verminderen. Beveiliging op kolomniveau elimineert ook de noodzaak voor de introductie van de weergave, waarbij u kolommen uitfiltert, om toegangsbeperkingen op 'Leo' op te leggen
De manier om beveiliging op kolomniveau te implementeren, is met behulp van de GRANT T-SQL-instructie. Met deze instructie ondersteunen SQL en Microsoft Entra ID de verificatie.
Syntaxis
De syntaxis die moet worden gebruikt voor het implementeren van beveiliging op kolomniveau ziet er als volgt uit:
GRANT <permission> [ ,...n ] ON
[ OBJECT :: ][ schema_name ]. object_name [ ( column [ ,...n ] ) ] // specifying the column access
TO <database_principal> [ ,...n ]
[ WITH GRANT OPTION ]
[ AS <database_principal> ]
<permission> ::=
SELECT
| UPDATE
<database_principal> ::=
Database_user // specifying the database user
| Database_role // specifying the database role
| Database_user_mapped_to_Windows_User
| Database_user_mapped_to_Windows_Group
Wanneer gebruikt u beveiliging op kolomniveau? Stel dat u een financiële dienstverlener bent en alleen een accountmanager mag hebben die toegang heeft tot het burgerservicenummer, telefoonnummer of andere persoonsgegevens van een klant. Het is noodzakelijk om de rol van een accountmanager te onderscheiden ten opzichte van de manager van de accountmanagers.
Een andere use case is mogelijk gerelateerd aan de gezondheidszorg. Stel dat u een specifieke zorgverlener hebt. Deze zorgverlener wil alleen dat artsen en verpleegsters toegang hebben tot medische dossiers. De factureringsafdeling mag geen toegang hebben om deze gegevens weer te geven. Beveiliging op kolomniveau kan de optie zijn om te gebruiken.
Hoe onderscheidt beveiliging op kolomniveau zich dan met beveiliging op rijniveau? Laten we daar eens naar kijken.
Beveiliging op rijniveau in Azure Synapse Analytics
Beveiliging op rijniveau (RLS) kan u helpen bij het maken van een groepslidmaatschap of uitvoeringscontext om niet alleen kolommen in een databasetabel te beheren, maar in feite de rijen. Beveiliging op rijniveau kan net als beveiliging op kolomniveau eenvoudig helpen en uw ontwerp en codering van uw toepassingsbeveiliging mogelijk maken. Vergeleken met beveiliging op kolomniveau waarbij deze zich richt op de kolommen (parameters), kunt u met RLS beperkingen voor toegang tot gegevensrijen implementeren. Stel dat uw werknemer alleen toegang heeft tot rijen met gegevens die belangrijk zijn voor de afdeling. U moet RLS implementeren. Als u bijvoorbeeld de toegang tot klantgegevens wilt beperken die alleen relevant is voor het bedrijf, kunt u beveiliging op rijniveau implementeren. De beperking voor de toegang van de rijen is een logica die zich in de databaselaag bevindt, in plaats van op de gegevenslaag op toepassingsniveau. Als Leo toegang nodig heeft tot gegevens uit elke laag, moet de database de toegangsbeperking toepassen telkens wanneer hij toegang probeert te krijgen tot gegevens uit een andere laag. De reden hiervoor is ervoor te zorgen dat uw beveiliging betrouwbaar en robuust is, omdat we het oppervlak van het algehele beveiligingssysteem verminderen.
De manier om beveiliging op rijniveau te implementeren, is met behulp van het CREATE SECURITY POLICY[! INCLUDEtsql]-instructie. De predicaten worden gemaakt als inline tabelwaardefuncties. Het is noodzakelijk om te begrijpen dat binnen Azure Synapse alleen filterpredicaten worden ondersteund. Als u een blokpredicaat wilt gebruiken, kunt u op dit moment geen ondersteuning vinden in Azure Synapse.
Beschrijving van beveiliging op rijniveau met betrekking tot filterpredicaten
RLS in Azure Synapse ondersteunt één type beveiligingspredicaten, dat filterpredicaten zijn, en geen predicaten blokkeren.
Wat filterpredicaten doen, is het op de achtergrond filteren van de rijen die beschikbaar zijn voor leesbewerkingen zoals SELECT, UPDATE, DELETE.
De toegang tot gegevens op rijniveau in een tabel wordt beperkt als een inline-tabelwaardefunctie. Dit is een beveiligingspredicaat. Deze tabelwaardefunctie wordt vervolgens aangeroepen en afgedwongen door het beveiligingsbeleid dat u nodig hebt. Een toepassing is niet op de hoogte van rijen die zijn gefilterd uit de resultatenset voor filterpredicaten. Wat er gebeurt, is dat als alle rijen worden gefilterd, een null-set wordt geretourneerd.
Wanneer u filterpredicaten gebruikt, wordt deze toegepast wanneer gegevens uit de basistabel worden gelezen. Het filterpredicaat is van invloed op alle get-bewerkingen, zoals SELECT, DELETE, UPDATE. U kunt geen rijen selecteren of verwijderen die zijn gefilterd. Het is niet mogelijk om een rij bij te werken die is gefilterd. Wat u kunt doen, is rijen bijwerken op een manier die later wordt gefilterd.
Gebruiksgevallen
We hebben al enkele use cases voor beveiliging op rijniveau genoemd. Een ander gebruiksvoorbeeld kan zijn wanneer u een toepassing met meerdere tenants hebt gemaakt waarin u een beleid maakt waarbij logische scheidingen van de gegevensrijen van een tenant van de gegevensrijen van een andere tenant worden afgedwongen. Om dit efficiënt te implementeren, wordt het ten zeerste aanbevolen om gegevens voor veel tenants in één tabel op te slaan.
Wanneer we RLS-filterpredicaten bekijken, zijn ze functioneel gelijk aan het toevoegen van een WHERE-component .
Het predicaat kan net zo geavanceerd zijn als het dicteren van bedrijfsprocedures, of de component kan net zo eenvoudig zijn als WHERE TenantId = 42
.
Wanneer we naar RLS kijken, introduceert RLS predicaattoegangsbeheer. De reden waarom RLS kan worden gebruikt voor predicaattoegangsbeheer is dat het een flexibele, gecentraliseerde evaluatie op basis van predicaat is. Het filterpredicaat kan worden gebaseerd op metagegevens of andere criteria die u op de juiste manier zou bepalen. Het predicaat wordt gebruikt als criterium om te bepalen of de gebruiker de juiste toegang heeft tot de gegevens op basis van gebruikerskenmerken. Toegangsbeheer op basis van labels kan worden geïmplementeerd met behulp van op predicaat gebaseerd toegangsbeheer.
Machtigingen
Als u het beveiligingsbeleid wilt maken, wijzigen of verwijderen, moet u de machtiging ALTER ANY SECURITY POLICY gebruiken. De reden hiervoor is dat wanneer u een beveiligingsbeleid maakt of neer zet, hiervoor ALTER-machtigingen voor het schema zijn vereist.
Daarnaast zijn er andere machtigingen vereist voor elk predicaat dat u zou toevoegen:
SELECT - en VERWIJZINGEN-machtigingen voor de inline-tabelwaardefunctie die als predicaat worden gebruikt.
DE MACHTIGING VERWIJZINGEN voor de tabel waarop u zich richt om te worden gebonden aan het beleid.
DE MACHTIGING VERWIJZINGEN voor elke kolom uit de doeltabel die als argumenten wordt gebruikt.
Zodra u het beveiligingsbeleid hebt ingesteld, zijn deze van toepassing op alle gebruikers (inclusief dbo-gebruikers in de database) Hoewel DBO-gebruikers beveiligingsbeleid kunnen wijzigen of verwijderen, kunnen hun wijzigingen in het beveiligingsbeleid worden gecontroleerd. Als u speciale omstandigheden hebt waarbij gebruikers met hoge bevoegdheden, zoals een systeembeheerder of db_owner, alle rijen moeten zien om problemen met gegevens op te lossen of te valideren, moet u het beveiligingsbeleid nog steeds schrijven om dat mogelijk te maken.
Als u een beveiligingsbeleid hebt gemaakt waarbij SCHEMABINDING = OFF
, om een query uit te voeren op de doeltabel, de gebruiker de machtiging SELECT of EXECUTE voor de predicaatfunctie moet hebben.
Ze hebben ook machtigingen nodig voor eventuele extra tabellen, weergaven of functies die in de predicaatfunctie worden gebruikt.
Als er een beveiligingsbeleid wordt gemaakt met SCHEMABINDING = ON
(de standaardinstelling), worden deze machtigingscontroles overgeslagen wanneer gebruikers query's uitvoeren op de doeltabel.
Aanbevolen procedures
Er zijn enkele aanbevolen procedures om rekening mee te houden wanneer u beveiliging op rijniveau wilt implementeren. We raden u aan een afzonderlijk schema te maken voor de RLS-objecten. RLS-objecten in deze context zijn de predicaatfuncties en beveiligingsbeleidsregels. Waarom is dat een best practice? Het helpt bij het scheiden van de machtigingen die vereist zijn voor deze speciale objecten van de doeltabellen. Daarnaast kan scheiding voor verschillende beleidsregels en predicaatfuncties nodig zijn in databases met meerdere tenants. Het is echter geen standaard voor elk geval.
Een andere best practice om in gedachten te houden, is dat de machtiging ALTER ANY SECURITY POLICY alleen moet zijn bedoeld voor gebruikers met hoge bevoegdheden (zoals een beveiligingsbeleidsbeheerder). De beveiligingsbeleidsbeheerder mag geen SELECT-machtiging vereisen voor de tabellen die ze beveiligen.
Om mogelijke runtimefouten te voorkomen, moet u rekening houden met typeconversies in predicaatfuncties die u schrijft. U moet ook proberen recursie in predicaatfuncties te voorkomen. De reden hiervoor is om prestatievermindering te voorkomen. Hoewel de queryoptimalisatie probeert de directe recursies te detecteren, is er geen garantie om de indirecte recursies te vinden. Met indirecte recursie bedoelen we waar een tweede functie de predicaatfunctie aanroept.
Het wordt ook aanbevolen om het gebruik van overmatige tabelsamenvoegingen in predicaatfuncties te voorkomen. Dit zou de prestaties maximaliseren.
Over het algemeen moet u proberen logica te vermijden die afhankelijk is van sessiespecifieke SET-opties. Hoewel dit zeer onwaarschijnlijk is om te worden gebruikt in praktische toepassingen, kunnen predicaatfuncties waarvan de logica afhankelijk is van bepaalde sessiespecifieke SET-opties informatie lekken als gebruikers willekeurige query's kunnen uitvoeren. Een predicaatfunctie die impliciet een tekenreeks converteert naar datum/tijd , kan bijvoorbeeld verschillende rijen filteren op basis van de optie SET DATEFORMAT voor de huidige sessie.