50
OBRONA
HAKIN9 5/2009
W
klasycznym modelu bezpieczeństwa
bazy danych Oracle dostęp do
obiektów przechowujących dane jest
realizowany za pomocą odpowiednich przywilejów
obiektowych.
Jeśli chcemy na przykład umożliwić jakiemuś
użytkownikowi możliwość odczytu danych z
pewnej, niebędącej jego własnością tabeli,
perspektywy, bądź też synonimu (w dalszej części
artykułu dla zachowania przejrzystości rozważań
będziemy posługiwali się tylko tabelami) należy
mu do takiego obiektu przyznać przywilej
SELECT
.
Przykładowo, jeśli chcielibyśmy umożliwić
odczyt danych z tabel pracownicy w schemacie
kp użytkownikowi jkowalski, należałoby użyć
polecenia z Listingu 1. (będąc zalogowanym
jako użytkownik kp lub inny mający prawo
przyznawania przywileju
SELECT
na tabeli
kp.pracownicy
):
Od tego momentu użytkownik jkowalski
może odczytywać wszystkie rekordy z tabeli
kp.pracownicy.
Rozwiązanie to posiada jednak ograniczenie
polegające na tym, że przyznając przywilej
SELECT
danemu użytkownikowi nie mamy
w żaden sposób możliwości ograniczenia,
które wiersze będzie mógł on odczytywać.
Przywilej
SELECT
działa tutaj bowiem globalnie
– umożliwiając odczyt wszystkich wierszy z danej
tabeli.
Nie zawsze jednak takie działanie jest
pożądane. Czasem (o zastosowaniach
DARIUSZ WALAT
Z ARTYKUŁU
DOWIESZ SIĘ
jak wykorzystać mechanizmy
bezpieczeństwa określane
mianem wirtualnej prywatnej
bazy danych w systemie
zarządzania bazą danych
Oracle.
CO POWINIENEŚ
WIEDZIEĆ
znać podstawy zarządzania
bazą danych Oracle 9i/10g,
mieć ogólne pojęcie o
programowaniu w języku SQL i
PL/SQL.
takiego podejścia opowiemy w dalszej części
artykułu) konieczne jest ograniczenie w sposób
niewidoczny dla użytkownika wykonującego
zapytanie zwracanych z danej tabeli rekordów
do pewnego ich podzbioru w oparciu o ściśle
określone kryteria. Rozwiązaniem takiego
problemu może być utworzenie odpowiednich
perspektyw pozwalających na dostęp tylko
do konkretnych rekordów z danej tabeli oraz
przyznanie do nich odpowiednich praw
konkretnym użytkownikom. Przykładowo,
gdybyśmy chcieli umożliwić odczyt z tabeli
kp.pracownicy dwóm użytkownikom, nazywającym
się
uzytkownik _ a
i
uzytkownik _ b
, w taki
sposób, aby
uzytkownik _ a
widział tylko
rekordy pracowników z działu o identyfikatorze
10
, natomiast
uzytkownik _ b
tylko rekordy
pracowników z działu o identyfikatorze
20
,
należałoby utworzyć dwie perspektywy, pierwszą,
nazywającą się na przykład
pracownicy _
dzial _ 10
, posiadającą w swoim kodzie
warunek
WHERE id _ dzialu = 10
, oraz drugą
(
pracownicy _ dzial _ 20
) posiadającą warunek
WHERE id _ dzialu = 20
, a następnie przyznać
przywilej
SELECT
na tych perspektywach do
użytkowników: odpowiednio
uzytkownik _ a
oraz
uzytkownik _ B
. Jak widać, jest to rozwiązanie
mało elastyczne; dodanie nowych użytkowników
w systemie determinuje konieczność tworzenia
nowych perspektyw i przyznawania do nich
uprawnień, zmiana numeracji działów wymusza
konieczność przepisania perspektyw, itd…, itd…
Stopień trudności
Fine Grained
Access Control
Większości użytkowników bazy danych firmy Oracle kojarzą się
zwykle jako „czarne skrzynki”. Jednak, aby dane te były bezpieczne
silniki bazodanowe mają zaimplementowaną sporą liczbę technologii
pozwalających przy ich umiejętnym wykorzystaniu mieć pewność, że
dane te pozostaną „nieskompromitowane”.
51
FINE GRAINED ACCESS CONTROL
HAKIN9
5/2009
Panaceum na ograniczenia
związane z powyższym problemem
jest wprowadzone w bazie danych 8i,
a w kolejnych wersjach rozszerzone
i udoskonalone rozwiązanie, które
pozwala na bardziej precyzyjne od
przywileju
SELECT
przyznawanie
uprawnień do odczytu danych z tabel.
Jest ono określane mianem Prywatnej
Wirtualnej Bazy Danych (ang. Virtual
Private Database, w skrócie VPD),
Drobnoziarnistej Kontroli Dostępu
(ang. Fine Grained Access Control, w
skrócie FGAC) lub też bezpieczeństwem
na poziomie wiersza (ang. Row Level
Security). W literaturze spotyka się
wszystkie trzy powyższe określenia,
natomiast oznaczają one dokładnie to
samo rozwiązanie, które jest fizycznie
realizowane za pomocą pakietu DBMS_
RLS. W dalszej części artykułu będziemy
się posługiwali zamiennie terminami VPD
lub FGAC.
Działanie FGAC – w dużym
uproszczeniu – polega na tym, że baza
danych w oparciu o pewien zestaw
kryteriów modyfikuje (poprzez dodanie
odpowiedniego warunku
WHERE
) w
tle zapytanie wysłane do niej przez
użytkownika. Dzięki temu użytkownik,
zamiast otrzymać pełen zestaw rekordów,
otrzymuje ich pewien podzbiór.
Przykładowo zapytanie z Listingu
3. może zostać zmodyfikowane przez
bazę danych w tle poprzez dodanie
odpowiedniego predykatu do postaci
przedstawionej na Listingu 4. gdzie
funkcja
USER
zwraca nazwę aktualnie
zalogowanego użytkownika. Tak więc,
będąc zalogowanym jako użytkownik
jkowalski zapytanie z Listingu 5. przyjmie
efektywnie postać jak na Listingu 6.
Jak więc widać jest to funkcjonalność,
która ma działanie podobne do
rozwiązania z perspektywami, o którym
wspominaliśmy powyżej. Jest jednak
niepomiernie bardziej elastyczne, gdyż tutaj
za generowanie odpowiedniego predykatu
odpowiada centralna funkcja, która jest
stowarzyszona z daną tabelą za pomocą
odpowiedniej polityki FGAC.
FGAC
– konfiguracja podstawowa
Pierwszym krokiem w konfiguracji FGAC
jest utworzenie odpowiedniej funkcji
Listing 1.
Przyznanie uprawnień SELECT na tabeli kp.pracownicy
kp@szkol>
GRANT
select
ON
pracownicy
TO
jkowalski;
Pomyślnie przyznano uprawnienia
Listing 2.
Odczytanie rekordów z tabeli kp.pracownicy
kp@szkol>
connect
jkowalski/jkowalski
Połączono.
jkowalski@szkol>
SELECT
*
FROM
kp.pracownicy;
ID_PRACOWNIKA IMIE NAZWISKO WYNAGRODZENIE ID_DZIALU
------------- ---------- ------------ ------------- ----------
1 Jan Kowalski 2300 10
2 Andrzej Nowak 5400 20
3 Zbigniew Wójcik 1850 10
4 Dariusz Walat 7900 20
5 Piotr Romańczuk 4670 10
6 Adam Kaczmarski 1100 20
6 wierszy zostało wybranych.
Listing 3.
Zapytanie pobierające wszystkie rekordy z tabeli kp.pracownicy
SELECT
*
FROM
kp.pracownicy;
Listing 4.
Zapytanie pobierające wiersze z tabeli kp.pracownicy z warunkiem filtrującym
SELECT
*
FROM
kp.pracownicy
WHERE
UPPER
(
nazwisko
)
= SUBSTR
(
USER
, 2
)
;
Listing 5.
Zapytanie pobierające wszystkie rekordy z tabeli kp.pracownicy
SELECT
*
FROM
kp.pracownicy;
Listing 6.
Zapytanie pobierające rekordy z tabeli kp.pracownicy dla pracownika(ów)
o nazwisku ‘KOWALSKI’
SELECT
*
FROM
kp.pracownicy
WHERE
UPPER
(
nazwisko
)
=
'KOWALSKI'
;
Listing 7.
Przykładowa funkcja polityki FGAC
CREATE
OR
REPLACE
FUNCTION
zwroc_nazwisko
(
p_schema
IN
VARCHAR2,
p_object
IN
VARCHAR2
)
RETURN
VARCHAR2
AS
BEGIN
IF
USER
=
'KP'
THEN
RETURN
NULL
;
ELSE
RETURN
'UPPER(nazwisko) = SUBSTR(USER, 2)'
;
END
IF
;
END
;
/
Listing 8.
Utworzenia polityki ‘PRACOWNICY_SELECT_POLICY’ na tabeli kp.pracownicy
kp@szkol>
BEGIN
2 dbms_rls.add_policy
(
3 object_schema =>
'KP'
,
4 object_name =>
'PRACOWNICY'
,
5 policy_name =>
'PRACOWNICY_SELECT_POLICY'
,
6 function_schema =>
'KP'
,
7 policy_function =>
'ZWROC_NAZWISKO'
,
8 statement_types =>
'SELECT'
9
)
;
10
END
;
11 /
OBRONA
52
HAKIN9 5/2009
FINE GRAINED ACCESS CONTROL
53
HAKIN9
5/2009
odpowiedzialnej za generowanie ciągów
tekstowych, które będą dopisywane
później jako predykaty do zapytań. Jest
to tak zwana funkcja polityki (ang. policy
function).
Funkcja ta jest następnie kojarzona
z konkretną tabelą za pomocą pakietu
DBMS _ RLS
poprzez utworzenie
odpowiedniej polityki. W niniejszym
artykule funkcjonalność FGAC jest
omawiana tylko i wyłącznie w aspekcie
zapytań
SELECT
wykonywanych w
odniesieniu do konkretnej tabeli.
Należy jednak zaznaczyć, że FGAC
może być również wykorzystywane do
transparentnego ograniczenia wierszy w
dowolnym poleceniu DML.
Dla powyżej określonego przykładu,
w którym chcemy ograniczyć rekordy
zwracane z tabeli kp.pracownicy tylko
do rekordu, w którym są dane aktualnie
zalogowanego użytkownika (za wyjątkiem
sytuacji, gdy jesteśmy zalogowanie
jako użytkownik kp, kiedy chcemy mieć
zwracane wszystkie rekordy z Tabeli
PRACOWNICY
), odpowiednia funkcja polityki
FGAC mogłaby wyglądać tak jak na
Listingu 7.
Należy w tym miejscu zwrócić uwagę, iż
każda funkcja polityki musi posiadać dwa
parametry wejściowe:
nazwa schematu (p_schema in varchar2);
nazwa tabeli (p_table in varchar2).
które są wykorzystywane później do
określenia tabeli, w odniesieniu do której
mają być generować odpowiednie
predykaty, oraz musi zwracać ciąg
znakowy, który będzie dopisywany
do dowolnego polecenia
SELECT
(w
naszym wypadku w stosunku do tabeli
kp.pracownicy).
Jak widać, nasza funkcja
zwroc _
nazwisko
w zależności od użytkownika
zwróci: ciąg pusty (dla użytkownika kp),
co w praktyce będzie oznaczało, że do
polecenia
SELECT
nie zostanie dodany
żaden predykat lub wartość będącą
wycinkiem z nazwy konta użytkownika
w przypadku wszystkich pozostałych
użytkowników.
Mając przygotowaną funkcję
polityki, kolejnym krokiem w konfiguracji
FGAC jest utworzenie polityki, która
będzie z niej korzystała. Do tego celu
Listing 9.
Pobranie informacji o polityce pracownicy_select_policy z perspektywy
USER_POLICIES
kp@szkol>
SELECT
object_name, policy_name, pf_owner function_owner,
FUNCTION
,
2 sel, ins, upd, del, ENABLE
3
FROM
user_policies;
OBJECT_NAME POLICY_NAME FUNCTION_OWN
FUNCTION
SEL INS UPD DEL ENA
------------ ------------------------------ ------------ -------------- --- --- --- --- ---
PRACOWNICY PRACOWNICY_SELECT_POLICY KP ZWROC_NAZWISKO YES NO NO NO YES
Listing 10.
Przykład działania polityki FGAC na tabeli kp.pracownicy
kp@szkol>
CONNECT
kp/kp
Połączono.
kp@szkol>
SELECT
*
FROM
pracownicy;
ID_PRACOWNIKA IMIE NAZWISKO WYNAGRODZENIE ID_DZIALU
------------- ---------- ------------ ------------- ----------
1 Jan Kowalski 2300 10
2 Andrzej Nowak 5400 20
3 Zbigniew Wójcik 1850 10
4 Dariusz Walat 7900 20
5 Piotr Romańczuk 4670 10
6 Adam Kaczmarski 1100 20
kp@szkol>
GRANT
SELECT
ON
pracownicy
TO
jkowalski, scott;
Pomyślnie przyznano uprawnienia.
kp@szkol>
CONNECT
jkowalski/jkowalski
Połączono.
jkowalski@szkol>
SELECT
*
FROM
kp.pracownicy;
ID_PRACOWNIKA IMIE NAZWISKO WYNAGRODZENIE ID_DZIALU
------------- ---------- ------------ ------------- ----------
1 Jan Kowalski 2300 10
jkowalski@szkol>
CONNECT
scott/tiger
Połączono.
scott@szkol>
SELECT
*
FROM
kp.pracownicy;
nie wybrano żadnych wierszy
Listing 11.
Efekt działania przywileju EXEMPT ACCESS POLICY
SQL>
CONNECT
scott/tiger
Połączono.
SCOTT@SZKOL>
SELECT
COUNT
(
*
)
FROM
kp.pracownicy;
COUNT
(
*
)
----------
0
SCOTT@SZKOL>
CONNECT
/
AS
sysdba
Połączono.
SYS@SZKOL>
GRANT
EXEMPT ACCESS POLICY
TO
scott;
Pomyślnie przyznano uprawnienia.
SYS@SZKOL>
CONNECT
SCOTT/TIGER
Połączono.
SCOTT@SZKOL>
SELECT
COUNT
(
*
)
FROM
kp.pracownicy;
COUNT
(
*
)
----------
6
OBRONA
52
HAKIN9 5/2009
FINE GRAINED ACCESS CONTROL
53
HAKIN9
5/2009
jest wykorzystywany wspomniany już
uprzednio pakiet DBMS_RLS. W tym
miejscu należy wyjaśnić, że przywilej
EXECUTE
umożliwiający wykorzystanie
pakietu DBMS_RLS do zarządzania
politykami FGAC jest uprawnieniem
potężnym. Każdy użytkownik posiadający
uprawnienie do uruchamiania
procedur z pakietu DBMS_RLS ma
możliwość modyfikowania i usuwania
już istniejących polityk utworzonych
przez innych użytkowników. Stąd
też w produkcyjnych rozwiązaniach
najlepiej utworzyć odpowiednie konto
użytkownika, które będzie jako jedyne
uprawnione do tworzenia polityk w
danym systemie. W ten sposób zostanie
ograniczone do niezbędnego minimum
niebezpieczeństwo niewłaściwego użycia
pakietu DBMS_RLS.
W naszym przykładzie załóżmy jednak,
że użytkownik kp ma możliwość posłużenia
się pakietem DBMS_RLS do utworzenia
polityki, która będzie korzystała z funkcji
zwroc _ nazwisk
o w celu ograniczenia
rekordów zwracanych przez zapytania do
kp.pracownicy.
Kod z Listingu 8 spowodował
utworzenie polityki
pracownicy _
select _ policy
w schemacie
użytkownika
kp
na tabeli pracownicy ze
schematu
kp
z wykorzystaniem funkcji
polityki
zwroc _ nazwisko
również ze
schematu
kp
.
Informacje o nowoutworzonej polityce
można znaleźć w perspektywie systemowej
USER _ POLICIES
Jak widać, utworzona przez nas
polityka jest domyślnie włączona, oraz
będzie działała tylko w odniesieniu do
zapytań.
No dobrze. Mamy w końcu utworzoną
odpowiednią politykę implementującą
FGAC na naszej przykładowej tabeli. Czas
najwyższy zobaczyć efekty jej działania.
Podłączymy się do bazy danych
najpierw jako właściciel tabeli pracownicy,
czyli użytkownik kp oraz wykonamy na
niej zapytanie. Następnie przyznamy
przywilej
SELECT
na tabeli pracownicy
dwóm innym użytkownikom – jkowalski i
scott oraz, logując się kolejno na ich konta,
zobaczymy efekt działania utworzonej
uprzednio polityki, wykorzystując przyznany
przywilej
SELECT
. Pokazane to zostało na
Listingu 10.
Listing 12.
Efekt działania polityki FGAC dla zapytania pobierającego wszystkie
kolumny z tabeli kp.pracownicy
jkowalski@szkol>
SELECT
*
FROM
kp.pracownicy;
ID_PRACOWNIKA IMIE NAZWISKO WYNAGRODZENIE ID_DZIALU
------------- ---------- ------------ ------------- ----------
1 Jan Kowalski 2300 10
Listing 13.
Domyślny efekt działania polityki FGAC dla zapytania pobierającego
pojedynczą kolumnę z tabeli kp.pracownicy
jkowalski@szkol>
SELECT
count
(
id_pracownika
)
FROM
kp.pracownicy;
COUNT
(
ID_PRACOWNIKA
)
--------------------
1
Listing 14.
Przykład polityki FGAC, działającej na poziomie pojedynczej kolumny
kp@SZKOL>
BEGIN
2 dbms_rls.add_policy
(
3 object_schema =>
'KP'
,
4 object_name =>
'PRACOWNICY'
,
5 policy_name =>
'PRACOWNICY_SELECT_POLICY'
,
6 function_schema =>
'KP'
,
7 policy_function =>
'ZWROC_NAZWISKO'
,
8 statement_types =>
'SELECT'
,
9 sec_relevant_cols =>
'WYNAGRODZENIE'
10
)
;
11
END
;
12 /
Procedura PL/SQL została zakończona pomyślnie.
Listing 15.
Wynik zapytania pobierającego wszystkie kolumny przy włączonej polityce
działającej na poziomie kolumny wynagrodzenie
jkowalski@szkol>
SELECT
*
FROM
kp.pracownicy;
ID_PRACOWNIKA IMIE NAZWISKO WYNAGRODZENIE ID_DZIALU
------------- ---------- ------------ ------------- ----------
1 Jan Kowalski 2300 10
Listing 16.
Wynik zapytania pobierającego kolumny inne niż wynagrodzenie przy
włączonej polityce działającej na poziomie kolumny wynagrodzenie
jkowalski@szkol>
SELECT
COUNT
(
id_pracownika
)
FROM
kp.pracownicy;
COUNT
(
ID_PRACOWNIKA
)
--------------------
6
jkowalski@szkol>
SELECT
id_pracownika, nazwisko, imie, id_dzialu
2
FROM
kp.pracownicy;
ID_PRACOWNIKA NAZWISKO IMIE ID_DZIALU
------------- ------------ ---------- ----------
1 Kowalski Jan 10
2 Nowak Andrzej 20
3 Wójcik Zbigniew 10
4 Walat Dariusz 20
5 Romańczuk Piotr 10
6 Kaczmarski Adam 20
6 wierszy zostało wybranych.
Listing 17.
Zapytanie pobierające wszytskie kolumny i wiersze z tabeli kp.pracownicy
jkowalski@szkol>
SELECT
*
FROM
kp.pracownicy;
OBRONA
54
HAKIN9 5/2009
FINE GRAINED ACCESS CONTROL
55
HAKIN9
5/2009
Jak widać, polityka
pracownicy _
select _ policy
zadziałała w sposób
prawidłowy. Dla użytkownika
kp
wykonany
SELECT
zwrócił wszystkie
wiersze, dla użytkownika jkowalski
funkcja polityki zwróciła predykat
where
UPPER(nazwisko) = ‘KOWALSKI’
, co
spowodowało zwrócenie pojedynczego
rekordu, natomiast dla użytkownika scott
funkcja polityki zwróciła predykat
where
UPPER(nazwisko) = ‘COTT’
, czego
efektem końcowym był brak zwróconych
rekordów w wyniku zadanego zapytania.
FGAC – wyłączenie
użytkowników z działania
polityki
Polityka FGAC utworzona na
danej tabeli jest uruchamiana dla
każdego użytkownika, mającego do
tej tabeli dostęp. Czasem jednak
zachodzi konieczność, aby dla
konkretnego użytkownika polityka
nie była egzekwowana. Typowym
przykładem takiej sytuacji jest operacja
przygotowywania kopii zapasowych,
gdzie działanie polityki FGAC jest wręcz
niepożądane, gdyż wykonując backup
bazy danych z reguły chcemy mieć w
nim wszystkie dane. Między innymi z tego
powodu w bazie danych Oracle istnieje
bardzo mocny przywilej systemowy
EXEMPT ACCESS POLICY
. Jako przywilej
systemowy nie jest on związany z
żadnym obiektem, tak więc użytkownik,
który go posiada, może obejść polityki
FGAC założone na wszystkich tabelach
w bazie danych. Warto odnotować, iż
użytkownicy podłączający się do bazy
danych z przywilejem
SYSDBA
mają
przywilej
EXEMPT ACCESS POLICY
włączony domyślnie.
Listing 11. prezentuje efekt działania
przywileju
EXEMPT ACCESS POLICY
przyznanego użytkownikowi
scott
.
FGAC na poziomie kolumny
Domyślnie polityka FGAC zakłada, iż
bez względu na to, jakie kolumny z tabeli
będą wykorzystane w instrukcji
SELECT
,
aplikowana jest odpowiednia funkcja
polityki.
Tak więc będąc zalogowanym jako
użytkownik jkowalski zapytanie z Listingu
12, który zwraca jeden wiersz, ale również
wynik polecenia przedstawionego na
Listingu 13, który daje informację, że w
tabeli kp.pracownicy znajduje się tylko
pojedynczy rekord.
Począwszy od bazy 10g możemy przy
tworzeniu polityki FGAC na danej tabeli
założyć, że będzie ona egzekwowana
tylko w przypadku dostępu do konkretnych
Listing 18.
Pożądany wynik zapytania z listingu 17, wartości w kolumnie wynagrodzenie mają wartość NULL
ID_PRACOWNIKA IMIE NAZWISKO WYNAGRODZENIE ID_DZIALU
------------- ---------- ------------ ------------- ----------
1 Jan Kowalski 2300 10
2 Andrzej Nowak
NULL
20
3 Zbigniew Wójcik
NULL
10
4 Dariusz Walat
NULL
20
5 Piotr Romańczuk
NULL
10
6 Adam Kaczmarski
NULL
20
Listing 19.
Przykład polityki FGAC wykorzystującej mechanizm maskowania kolumn
BEGIN
dbms_rls.add_policy
(
object_schema =>
'KP'
,
object_name =>
'PRACOWNICY'
,
policy_name =>
'PRACOWNICY_SELECT_POLICY'
,
function_schema =>
'KP'
,
policy_function =>
'ZWROC_NAZWISKO'
,
statement_types =>
'SELECT'
,
sec_relevant_cols =>
'WYNAGRODZENIE'
,
sec_relevant_cols_opt => dbms_rls.all_rows
)
;
END
;
Listing 20.
Zapytanie zwracające informacje o zaaplikowanej do oryginalnego polecenia polityce FGAC oraz wygenerowanym przez
nią warunku WHERE
SQL>
SELECT
object_owner owner, object_name, policy, TO_CHAR
(
sql_fulltext
)
sql, predicate
2
FROM
v$vpd_policy p, v$sql s
3
WHERE
p.sql_id = s.sql_id
4
AND
predicate
IS
NOT
NULL
5 /
OWNER OBJECT_NAME POLICY SQL PREDICATE
-------- ------------ ------------------------ ----------------------------------- -----------------
----------------
KP PRACOWNICY PRACOWNICY_SELECT_POLICY
SELECT
COUNT
(
*
)
FROM
kp.pracownicy UPPER
(
nazwisko
)
=
SUBSTR
(
USER
, 2
)
KP PRACOWNICY PRACOWNICY_SELECT_POLICY
select
*
from
kp.pracownicy UPPER
(
nazwisko
)
=
SUBSTR
(
USER
, 2
)
OBRONA
54
HAKIN9 5/2009
FINE GRAINED ACCESS CONTROL
55
HAKIN9
5/2009
kolumn. Innymi słowy, tak długo, jak nie
będziemy próbowali zajrzeć do danych
z podlegającej polityce FGAC, kolumny
zapytania będą zwracały wszystkie rekordy
z tabeli. Jest to realizowane za pomocą
nowego parametru
SEC _ RELEVANT _
COLS
w procedurze
DBMS _ RLS.ADD _
POLICY
.
Przykładowo załóżmy, że polityka
pracownicy_select_policy powinna
być uruchamiana tylko wtedy, gdy w
odpowiednim poleceniu SELECT nastąpi
odwołanie do kolumny wynagrodzenie
(jawne bądź też niejawne – np. w
przypadku wykorzystania znaku * do
odwołania do wszystkich kolumn w tabeli).
Odpowiednia polityka będzie miała
postać taką jak na Listingu 14.
Po jej utworzeniu wykonajmy
kilka zapytań z poziomu użytkownika
jkowalski. Kwerenda z Listingu 15
zwraca w dalszym ciągu pojedynczy
rekord, ponieważ
*
jest rozwijana
do nazw wszystkich kolumn w tabeli
kp.pracownicy, ale już zapytania z
Listingu 16. powodują zwrócenie
odpowiednio wartości 6 jako liczby
wierszy w tabeli oraz wszystkich
rekordów z tabeli
kp.pracownicy
.
FGAC
– maskowanie kolumn
Załóżmy teraz, że będąc w dalszym
ciągu zalogowanym jako użytkownik
jkowalski chcielibyśmy, aby wynik
zapytania przedstawionego na Listingu
17. wyglądał jak na Listingu 18. gdzie
NULL
jest wartością pustą. Tak więc
chcemy, aby były zwracane wszystkie
wiersze z tabeli, również i te rekordy, które
zawierają poufne dane (w tym wypadku o
wynagrodzeniu), ale aby dane z wrażliwej
kolumny, do której nie powinniśmy mieć
dostępu z tytułu nałożonej polityki FGAC
były wyświetlane jako wartości puste,
natomiast rekord, do którego powinniśmy
mieć dostęp miał wyświetlaną
rzeczywistą wartość.
Począwszy od bazy danych Oracle w
wersji 10g jest to możliwe do zrealizowania
za pomocą kolejnego nowego parametru
procedury
DBMS _ RLS.ADD _ POLICY
–
sec _ relevant _ cols _ opt
, który
ustawiony na wartość
dbms _ rls.all _
rows
spowoduje opisane powyżej
zachowanie się polityki FGAC.
Kod w Listingu 19. przedstawia jego
wykorzystanie.
FGAC – podgląd
oryginalnego polecenia SQL
oraz zaaplikowanej polityki
W przypadku problemów z określeniem
przyczyny, dla której zestaw zwracanych
danych po wydaniu zapytania do tabeli
jest inny od spodziewanego przez
użytkownika, przydatna może się okazać
wiedza, w jakiej perspektywie systemowej
znajdują się informacje o politykach
zaaplikowanych do konkretnych poleceń
SQL. W bazie danych Oracle taką
perspektywą jest
v$vpd _ policy
, która
po połączeniu za pomocą kolumny
sql _ id
z perspektywą
v$sql
pozwala
na wyświetlenie zarówno oryginalnie
wykonanego polecenia SQL, jak i również
predykatu do niego dołączonego.
Listing 20 pokazuje, że w systemie przy
wykonaniu instrukcji:
SELECT COUNT(*) FROM kp.pracownicy;
oraz
SELECT * from kp.pracownicy;
została wykorzystana polityka
FGAC
PRACOWNICY _ SELECT _ POLICY
, która
spowodowała dodanie do każdego
z nich predykatu w postaci
WHERE
UPPER(nazwisko) =
SUBSTR(USER, 2)
.
FGAC – zastosowanie
Możliwości zastosowania funkcjonalności
FGAC, dostępnej w bazie danych Oracle
począwszy od wersji 8i, są wielorakie,
począwszy od prostego limitowania
użytkownikom dostępności do informacji
zawartych w danej tabeli w zależności
od posiadanych przez nich poziomów
uprawnień, weryfikowanych przez funkcję
polityki, poprzez sztuczki polegające na
celowym zaaplikowaniu odpowiedniej
polityki w celu wykonania operacji
eksportu tylko z określonym podzbiorem
rekordów, a skończywszy na budowaniu
systemów bazodanowych, które mogą
być bezpiecznie, a zarazem jednocześnie
udostępniane w Internecie wielu
klientom. To ostatnie rozwiązanie jest
chyba jedną z ciekawszych propozycji
wykorzystania FGAC, szczególnie dla
dostawców systemów webowych, gdzie
pojedynczy system, oparty o pojedynczą
bazę danych z jednym zestawem
tabel/perspektyw/synonimów, może być
jednocześnie wykorzystywany przez wielu
klientów, a aplikowane w przezroczysty
sposób polityki FGAC będą pozwalały
na bezpieczne odseparowanie danych
poszczególnych klientów w ramach
pojedynczej bazy danych. Można sobie
wyobrazić w skrajnym wypadku dostępny
jako usługa serwis służący do obsługi
kadrowo-płacowej pracowników różnych
firm. W takim przypadku do wszystkich
tabel/perspektyw, znajdujących się w
takim systemie, należałoby bowiem
dodać tylko kolumnę (jest to oczywiście
pewne uproszczenie zagadnienia),
nazywającą się przykładowo
id _ firmy
,
w której składowany byłby identyfikator
konkretnej firmy, oraz zaaplikować na
poszczególnych tabelach polityki FGAC,
które korzystałyby z funkcji zwracających
predykat typu
WHERE id _ firmy =
identyfikator _ danej _ firmy
, aby
możliwe było zupełnie transparentne
korzystanie z systemu przez wiele
przedsiębiorstw.
Podsumowanie
W artykule przedstawiono podstawowe
cechy FGAC, które (mam taką nadzieję)
pozwolą czytelnikowi wyrobić sobie
zdanie na temat jego możliwości. Ze
względu na ograniczone wielkością
pisma miejsce nie znalazły się w nim
jednak opisy i przykłady wykorzystania
bardziej zaawansowanych technik, takich
jak chociażby różnych typów funkcji
polityki FGAC (domyślny, dynamiczny typ
powoduje każdorazowe uruchamianie
funkcji w momencie odwołania do tabeli,
na której jest założona polityka, co może
negatywnie wpływać na wydajność
rozwiązania), wykorzystania obiektu
typu
CONTEXT
do ustawiania wartości
atrybutów, w oparciu, o które funkcja
polityki generowałaby odpowiedni
warunek dołączany do oryginalnego
zapytania, czy chociażby obsługi poleceń
DML w kontekście FGAC.
Dariusz Walat
Od ponad pięciu lat współpracuje z firmą Combidata
prowadząc szkolenia z technologii bazodanowych
Oracle w ramach Oracle University.
Kontakt z autorem: dwalat@epf.pl