sql >> Database teknologi >  >> RDS >> Sqlserver

Introduktion til Row-Level Security i SQL Server

Hvorfor er rækkeniveausikkerhed vigtig?

Før SQL Server 2016 var sikkerhed på tabelniveau det laveste sikkerhedsniveau som standard for en database. Med andre ord kan en bruger være begrænset til at få adgang til en tabel som helhed. Men i nogle tilfælde har vi brug for, at brugerne har adgang til en tabel, men ikke til bestemte rækker i tabellen. Før SQL Server 2016 krævede dette, at brugerdefinerede lagrede procedurer blev skrevet for at levere en sådan finmasket sikkerhed. Sådanne lagrede procedurer er imidlertid tilbøjelige til SQL-injektion og andre sikkerhedsforbehold.

Brug af SQL Server Row Level Security-funktion i praksis

SQL Server 2016 introducerede en ny sikkerhedsfunktion på rækkeniveau, som giver brugerne mulighed for at få adgang til en tabel, men begrænser dem til at få adgang til specifikke rækker i den tabel. Lad os tage et kig på, hvordan dette kan bruges praktisk.

Beskrivelse

Der er fire trin til implementering af sikkerhed på rækkeniveau i SQL Server.

  1. Giv Select-tilladelser til brugerne på bordet, hvor du vil implementere sikkerhed på rækkeniveau.
  2. Dernæst skal du skrive en inline-tabelværdifunktion, der indeholder et filterprædikat. Tilføj filterlogikken til filterprædikatet.
  3. Til sidst skal du binde filterprædikatet, som du oprettede i andet trin, til en sikkerhedspolitik.
  4. Test sikkerhedsfunktionen på rækkeniveau.

Før vi udfører ovenstående trin, skal vi oprette en dummy-database med nogle dummy-poster. Udfør følgende script for at gøre det:

CREATE DATABASE UniversityGOUSE UniversityGOUSE UniversityCREATE TABEL Personer(Id INT PRIMÆR NØGLEIDENTITET(1,1),Navn VARCHAR (50),Rolle VARCHAR (50))GOUSE UniversitetINDSÆT I Personer VÆRDIER ('Sally', 'Principal' )INSERT INTO Persons VALUES ('Edward', 'Student' )INSERT INTO Persons VALUES ('Jon', 'Student' )INSERT INTO Persons VALUES ('Scot', 'Student')INSERT INTO Persons VALUES ('Ben', 'Student' ) INSERT INTO Persons VALUES ('Isabel', 'Teacher' )INSERT INTO Persons VALUES ('David', 'Lærer' )INSERT INTO Persons VALUES ('Laura', 'Lærer' )INSERT INTO Persons VALUES ('Jean', 'Lærer' ')INSERT INTO Persons VALUES ('Francis', 'Lærer' )

I scriptet opretter vi en dummy-database "Universitet". Dernæst udfører vi scriptet, der opretter en tabel med navnet "Personer". Hvis du ser på tabeldesignet, kan du se, at det indeholder tre kolonner Id, Name og Rolle. Id-kolonnen er den primære nøglekolonne med IDENTITY-begrænsning. Kolonnen Navn indeholder navnet på personen, og kolonnen Rolle indeholder personens rolle. Til sidst indsatte vi 10 poster i tabellen Personer. Tabellen har 1 rektor, 4 lærere og 5 elever.

Lad os udføre en simpel SELECT-sætning for at se poster i tabellen:

Brug UniversitySELECT * FROM Persons

Resultatet ser således ud:

Vi ønsker, at brugeren ved navn Principal skal have adgang til alle rækkerne i tabellen Personer. På samme måde bør en lærer kun have adgang til lærerens optegnelser, mens studerende kun skal have adgang til elevoptegnelserne. Dette er et klassisk tilfælde af sikkerhed på rækkeniveau.

For at implementere rækkeniveausikkerheden vil vi følge de trin, vi diskuterede tidligere.

Trin 1:Giv udvalgte tilladelser til brugere på bordet

Lad os oprette tre brugere med rollerne Rektor, Lærer og Elev og give dem SELECT-adgang til disse brugere i tabellen Personer. Udfør følgende script for at gøre det:

OPRET BRUGER Rektor UDEN LOGIN;GOGRANT SELECT ON Personer TIL Lærer;GOGRANT SELECT ON Personer TIL Studerende;GOGRANT SELECT ON Personer TIL Studerende;GOGRANT SELECT ON Personer TIL Studerende;GOGRANT 

Trin 2:Oprettelse af filterprædikat

Når brugerne har fået tilladelser, er næste trin at oprette et filterprædikat.

Følgende script gør det:

Brug UniversityGOCREATE FUNCTION dbo.fn_SP_Person(@Role AS sysname) RETURNS TABLEWITH SCHEMABINDINGAS RETURN SELECT 1 AS fn_SP_Person_output -- Prædikatlogik WHERE @Role =USER_NAME() ELLER USER_NAME>()'; 

Filterprædikatet er oprettet inde i en inline-tabelvurderet funktion og tager brugerens rolle som en parameter. Det returnerer de poster, hvor rolleværdien, der er sendt som en parameter, matcher rolleværdien i kolonnen Rolle. Eller hvis brugerrollen er 'Principal', returneres alle rollerne. Hvis du ser på prædikatfilteret, finder du ikke det tabelnavn, som vi laver filteret for. Filterprædikatet er forbundet til tabellen via den sikkerhedspolitik, som vi vil se i næste trin.

Trin 3:Oprettelse af en sikkerhedspolitik

Udfør følgende script for at oprette en sikkerhedspolitik for filterprædikatet, som vi oprettede i sidste trin:

Brug UniversityGoCREATE SIKKERHEDSPOLITIK RoleFilterADD FILTER PREDICATE dbo.fn_SP_Person(Role)ON dbo.PersonsWITH (STATE =ON);GO

I sikkerhedspolitikken har vi blot tilføjet det filterprædikat, vi oprettede, til tabellen Personer. For at aktivere politikken skal "STATE"-flaget sættes til ON.

Trin 4:Test af sikkerhed på rækkeniveau

Vi udførte alle de nødvendige trin for at håndhæve sikkerhed på rækkeniveau på tabellen Personer i universitetets database. Lad os først prøve at få adgang til posterne i tabellen Personer via standardbruger. Udfør følgende script:

Brug UniversitySELECT * FROM Persons;GO

Du vil ikke se noget i outputtet, da standardbrugeren ikke kan få adgang til tabellen Personer.

Lad os skifte til elevbrugeren, som vi oprettede tidligere, og prøve at VÆLGE poster fra tabellen Personer:

EXECUTE AS USER ='Student';Brug UniversitySELECT * FROM Personer; -- Kun elevoptegnelserREVERT;GO

I scriptet ovenfor skifter vi til 'Student'-brugeren, valgte poster fra tabellen Personer og vender tilbage til standardbrugeren. Outputtet ser således ud:

Du kan se, at på grund af sikkerheden på rækkeniveau, vises kun poster, hvor kolonnen Rolle har værdien Elev.

På samme måde vil brugeren Lærer kun have adgang til poster, hvor Rolle-kolonnen har værdien Lærer. Udfør følgende script for at bekræfte dette:

EXECUTE AS USER ='Lærer';Brug UniversitySELECT * FROM Personer; -- All RecordsREVERT;GO

I outputtet vil du have følgende poster:

Til sidst implementerede vi i vores filterprædikat logikken om, at brugeren Principal kan få adgang til alle posterne. Lad os bekræfte dette ved at udføre følgende forespørgsel:

EXECUTE AS USER ='Principal';Brug UniversitySELECT * FROM Personer; -- All RecordsREVERT;GO

I outputtet vil du se alle posterne som vist nedenfor:

Konklusion

Sikkerhedsfunktionen på rækkeniveau er yderst nyttig, når du ønsker, at brugere skal have finmasket adgang til specifikke data. Sikkerhedsfunktionen på rækkeniveau involverer dog en inline-tabel-vurderet funktion, som kan få dig til at få et præstationshit.

Som en tommelfingerregel, hvis du planlægger at bruge en simpel WHERE-sætning i prædikatfunktionen, bør din præstation ikke blive påvirket. På den anden side bør komplekse join-sætninger, der involverer opslagstabeller, undgås, når du har implementeret sikkerhed på rækkeniveau.


  1. Laravel 5 PDOException kunne ikke finde driver

  2. 10 bedste startups i cloud – 2018

  3. Lagring af UTF-16/Unicode-data i SQL Server

  4. Hvorfor tager Microsoft SQL Server 2012-forespørgsler minutter over JDBC 4.0, men sekund(er) i Management Studio?