Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Wprowadzenie do zabezpieczeń na poziomie wiersza w SQL Server

Dlaczego bezpieczeństwo na poziomie wiersza ma znaczenie?

Przed SQL Server 2016 zabezpieczenia na poziomie tabeli były domyślnym najniższym poziomem zabezpieczeń bazy danych. Innymi słowy, użytkownik może mieć ograniczony dostęp do tabeli jako całości. Jednak w niektórych przypadkach potrzebujemy, aby użytkownicy mieli dostęp do tabeli, ale nie do określonych wierszy w tabeli. Przed wersją SQL Server 2016 wymagało to napisania niestandardowych procedur przechowywanych w celu zapewnienia tak precyzyjnych zabezpieczeń. Jednak takie procedury składowane są podatne na wstrzyknięcie SQL i inne ograniczenia bezpieczeństwa.

Używanie funkcji zabezpieczeń na poziomie wiersza SQL Server w praktyce

SQL Server 2016 wprowadził nową funkcję zabezpieczeń na poziomie wiersza, która umożliwia użytkownikom dostęp do tabeli, ale ogranicza ich dostęp do określonych wierszy w tej tabeli. Przyjrzyjmy się, jak można to wykorzystać w praktyce.

Opis

Istnieją cztery kroki do wdrożenia zabezpieczeń na poziomie wiersza w SQL Server.

  1. Przyznaj uprawnienia Select użytkownikom w tabeli, w której chcesz zaimplementować zabezpieczenia na poziomie wiersza.
  2. Następnie musisz napisać funkcję wartości w tabeli śródliniowej zawierającą predykat filtra. Dodaj logikę filtra do predykatu filtra.
  3. Na koniec musisz powiązać predykat filtra, który utworzyłeś w drugim kroku, z polityką bezpieczeństwa.
  4. Przetestuj funkcję bezpieczeństwa na poziomie wiersza.

Zanim wykonamy powyższe kroki, musimy utworzyć fikcyjną bazę danych z kilkoma fikcyjnymi rekordami. W tym celu wykonaj następujący skrypt:

UTWÓRZ BAZĘ DANYCH UniwersytetGOUSE UniwersytetGOUSE UniwersytetCREATE TABLE Osoby(Id INT PRIMARY KEY IDENTITY(1,1),Nazwa VARCHAR (50),Rola VARCHAR (50))GOUSE UniwersytetWSTAWIĆ Osoby WARTOŚCI ('Sally', 'Principal' )INSERT INTO Osoby WARTOŚCI ('Edward', 'Student' )WSTAW W Osoby WARTOŚCI ('Jon', 'Student' )WSTAW W Osoby WARTOŚCI ('Scot', 'Student')WSTAW W Osoby WARTOŚCI ('Ben', 'Student' ) WPISAĆ WARTOŚCI OSÓB ('Isabel', 'Nauczyciel' )WSTAWIĆ WARTOŚCI OSÓB ('Dawid', 'Nauczyciel' )WSTAWIĆ WARTOŚCI OSÓB ('Laura', 'Nauczyciel' )WPISAĆ WARTOŚCI OSÓB ('Jean', 'Nauczyciel' ')WSTAW W Osoby WARTOŚCI ('Franciszek', 'Nauczyciel')

W skrypcie tworzymy fikcyjną bazę danych „Uniwersytet”. Następnie wykonujemy skrypt, który tworzy tabelę o nazwie „Osoby”. Jeśli spojrzysz na projekt tabeli, zobaczysz, że zawiera trzy kolumny Id, Nazwa i Rola. Kolumna Id jest kolumną klucza podstawowego z ograniczeniem IDENTITY. Kolumna Name zawiera imię i nazwisko osoby, a kolumna Role zawiera rolę osoby. Na koniec wstawiliśmy 10 rekordów do tabeli Osoby. Stół ma 1 dyrektora, 4 nauczycieli i 5 uczniów.

Wykonajmy prostą instrukcję SELECT, aby zobaczyć rekordy w tabeli:

Użyj UniwersytetuWYBIERZ * Z OSÓB

Wynik wygląda tak:

Chcemy, aby użytkownik o nazwie Principal miał dostęp do wszystkich wierszy w tabeli Osoby. Podobnie, Nauczyciel powinien mieć dostęp tylko do rekordów Nauczyciela, podczas gdy Uczniowie powinni mieć dostęp tylko do rekordów Studenta. To klasyczny przypadek bezpieczeństwa na poziomie wiersza.

Aby wdrożyć zabezpieczenia na poziomie wiersza, wykonaj kroki, które omówiliśmy wcześniej.

Krok 1:Przyznaj uprawnienia wyboru użytkownikom ze stołu

Utwórzmy trzech użytkowników z rolami dyrektora, nauczyciela i ucznia i przyznajmy im dostęp SELECT do tych użytkowników w tabeli Osoby. W tym celu wykonaj następujący skrypt:

UTWÓRZ UŻYTKOWNIKA Dyrektora BEZ LOGOWANIA;GOCREATE UŻYTKOWNIKA Nauczyciel BEZ LOGOWANIA;GOCREATE USER Uczeń BEZ LOGOWANIA;GOUżyj UczelniGRANT WYBIERZ Osoby do dyrektora;GOGRANT WYBIERZ Osoby do nauczyciela;GOGRANT WYBIERZ Osoby do ucznia;GO

Krok 2:Tworzenie predykatu filtra

Po przyznaniu użytkownikom uprawnień następnym krokiem jest utworzenie predykatu filtra.

Robi to następujący skrypt:

Użyj FUNKCJI UniversityGOCREATE dbo.fn_SP_Person(@Role AS nazwa_systemu) ZWRACA TABELĘZ SCHEMATAMI RETURN SELECT 1 AS fn_SP_Person_output -- Logika predykatów WHERE @Role =NAZWA_UŻYTKOWNIKA() OR NAZWA_UŻYTKOWNIKA() ='Podstawowy>'; 

Predykat filtra jest tworzony wewnątrz wbudowanej funkcji z wartościami przechowywanymi w tabeli i przyjmuje rolę użytkownika jako parametr. Zwraca te rekordy, w których wartość roli przekazana jako parametr odpowiada wartości roli w kolumnie Rola. Lub jeśli rola użytkownika to „Principal”, wszystkie role są zwracane. Jeśli spojrzysz na filtr predykatów, nie znajdziesz nazwy tabeli, dla której tworzymy filtr. Predykat filtra jest połączony z tabelą za pomocą polityki bezpieczeństwa, którą zobaczymy w następnym kroku.

Krok 3:Tworzenie polityki bezpieczeństwa

Wykonaj następujący skrypt, aby utworzyć politykę bezpieczeństwa dla predykatu filtra, który utworzyliśmy w ostatnim kroku:

Użyj UniversityGoCREATE POLITYKA BEZPIECZEŃSTWA RoleFilterDODAJ FILTR PREDYKACJA dbo.fn_SP_Person(Role)ON dbo.PersonsWITH (STAN =ON);GO

W Polityce bezpieczeństwa po prostu dodaliśmy predykat filtra, który stworzyliśmy do tabeli Osoby. Aby włączyć tę zasadę, flaga „STAN” powinna być ustawiona na WŁ.

Krok 4:Testowanie zabezpieczeń na poziomie wiersza

Wykonaliśmy wszystkie kroki potrzebne do wymuszenia zabezpieczeń na poziomie wiersza w tabeli Osoby w bazie danych Uniwersytetu. Spróbujmy najpierw uzyskać dostęp do rekordów w tabeli Osoby przez domyślnego użytkownika. Wykonaj następujący skrypt:

Użyj UniwersytetuWYBIERZ * FROM Osoby;GO

Nie zobaczysz nic w danych wyjściowych, ponieważ domyślny użytkownik nie ma dostępu do tabeli Osoby.

Przejdźmy do utworzonego wcześniej użytkownika Studenta i spróbujmy WYBRAĆ rekordy z tabeli Osoby:

EXECUTE AS USER ='Student';Użyj UniwersytetSELECT * FROM Osoby; -- Tylko rekordy uczniówREVERT;GO

W powyższym skrypcie przełączamy się na użytkownika „Student”, wybieramy rekordy z tabeli Osoby i wracamy z powrotem do użytkownika domyślnego. Wynik wygląda tak:

Możesz zobaczyć, że dzięki zabezpieczeniom na poziomie wiersza wyświetlane są tylko rekordy, w których kolumna Rola ma wartość Student.

Podobnie, użytkownik Nauczyciel będzie miał dostęp tylko do rekordów, w których kolumna Rola ma wartość Nauczyciel. Wykonaj następujący skrypt, aby to sprawdzić:

EXECUTE AS USER ='Nauczyciel';Użyj UniwersytetuSELECT * FROM Osoby; -- Wszystkie rekordyREVERT;GO

W danych wyjściowych pojawią się następujące rekordy:

Wreszcie w naszym predykacie filtrującym zaimplementowaliśmy logikę, dzięki której główny użytkownik może uzyskać dostęp do wszystkich rekordów. Zweryfikujmy to, wykonując następujące zapytanie:

EXECUTE AS USER ='Principal';Użyj UniwersytetuSELECT * FROM Osoby; -- Wszystkie rekordyREVERT;GO

W danych wyjściowych zobaczysz wszystkie rekordy, jak pokazano poniżej:

Wniosek

Funkcja zabezpieczeń na poziomie wiersza jest niezwykle przydatna, gdy chcesz, aby użytkownicy mieli szczegółowy dostęp do określonych danych. Jednak funkcja zabezpieczeń na poziomie wiersza obejmuje wbudowaną funkcję z wartościami w tabeli, co może spowodować spadek wydajności.

Zasadniczo, jeśli planujesz użyć prostej klauzuli WHERE w funkcji predykatu, nie powinno to wpłynąć na wydajność. Z drugiej strony, gdy zaimplementowano zabezpieczenia na poziomie wiersza, należy unikać złożonych instrukcji złączenia zawierających tabele przeglądowe.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Zrozumienie analizatora obciążenia w celu mapowania wąskich gardeł wydajności

  2. Jak przekonwertować z jednego formatu daty na inny w programie SQL Server za pomocą funkcji CONVERT()

  3. Funkcje rankingowe w SQL Server

  4. Wydajność serwera SQL TOP IO Query -1

  5. Model odzyskiwania zmian SQL Server