Utveckling av Àmnet och för ett utförligt svar till
Den anvĂ€nda strategin innebĂ€r konceptet "AffĂ€rslogik i databasen", vilket beskrivits mer detaljerat hĂ€r â
Den teoretiska delen Ă€r utmĂ€rkt beskriven i dokumentationen â . Nedan diskuteras en praktisk tillĂ€mpning av en specifik affĂ€rsuppgift â en rollbaserad Ă„tkomstmodell till data.

Artikeln innehĂ„ller ingenting nytt, inga dolda betydelser eller hemliga insikter. Det Ă€r bara en skiss av praktisk tillĂ€mpning av en teoretisk idĂ©. Om nĂ„gon Ă€r intresserad â lĂ€s. Om inte â slösa inte din tid.
UppgiftsstÀllande
Det Àr nödvÀndigt att begrÀnsa Ätkomst till att visa/infoga/Àndra/ta bort dokument i enlighet med anvÀndarens roll i applikationen. Med roll avses en post i tabellen roles kopplad med en mÄnga-till-mÄnga-relation till tabellen users. Detaljer om genomförande av tabeller utelÀmnas pÄ grund av trivialitet. Specifika detaljer relaterade till ÀmnesomrÄdet har ocksÄ utelÀmnats.
Implementering
Vi skapar roller, scheman och tabeller
Skapande av databasobjekt
CREATE ROLE store;
CREATE SCHEMA store AUTHORIZATION store;
CREATE TABLE store.docs
(
id integer , --dokumentets id
man_id integer , --dokumentets manager id
stat_id integer , --dokumentets status id
...
is_del BOOLEAN DEFAULT FALSE
);
ALTER TABLE store.docs ADD CONSTRAINT doc_pk PRIMARY KEY (id);
ALTER TABLE store.docs OWNER TO store ;
Vi skapar funktioner för att genomföra RLS
Kontroll av möjligheten att utföra SELECT pÄ en rad
check_select
SKAPA ELLER ERSĂTT FUNKTION store.check_select ( current_id store.docs.id%TYPE ) RETURNERAR boolean AS $$
DECLARERA
resultat boolean ;
curr_pid integer ;
curr_stat_id integer ;
doc_man_id integer ;
BĂRJA
-- DBA har Ätkomst till alla dokument
IF SESSION_USER = 'curr_dba'
DĂ
RETURERA TRUE ;
SLUTA ;
--------------------------------
--Om dokumentet har etiketten 'borttaget' - visa inte i urvalet
VĂLJ
is_del
IN
resultat
FRĂ
N
store.docs
WHERE
id = current_id ;
IF resultat = TRUE
THEN
RETURERA FALSE ;
SLUTA ;
--------------------------------
--HÀmta id för nuvarande anvÀndare
VĂLJ
service_function.get_curr_pid ()
IN
curr_pid ;
--------------------------------
--HÀmta id för dokumentets ansvarige
VĂLJ
man_id
IN
doc_man_id
FRĂ
N
store.docs
WHERE
id = current_id ;
--------------------------------
--Om dokumentets ansvarige inte Àr nuvarande anvÀndare eller ansvarig inte Àr angiven
--lÀgg till dokumentet i urvalet
IF doc_man_id != curr_pid OR doc_man_id ĂR NULL
THEN
RETURERA TRUE ;
ANNARS
--HĂ€mta dokumentets nuvarande status
VĂLJ
stat_id
IN
curr_statid
FRĂ
N
store.docs
WHERE
id = current_id ;
--Om status tillÄter att dokumetet visas - lÀgg till dokumentet i urvalet
IF curr_statid = 4 ELLER curr_statid = 9
DĂ
RETURERA TRUE ;
ANNARS
--Annars - uteslut dokumentet frÄn urvalet
RETURERA FALSE ;
SLUTA ;
SLUTA ;
--------------------------------
RETURERA FALSE ;
SLUTA
$$ SPRĂ
K plpgsql SECURITY DEFINER;
ALTERERA FUNKTION store.check_select( store.docs.id%TYPE ) ĂGARE TILL store ;
Ă
TERKALLA UTFĂRANDE PĂ
FUNKTION store.check_select( store.docs.id%TYPE ) FRĂ
N public;
BEVAKA UTFĂRANDE PĂ
FUNKTION store.check_select( store.docs.id%TYPE ) TILL service_functions;
Kontrollera möjligheten att utföra INSERT av en rad
check_insert
SKAPA ELLER ERSĂTT FUNKTION store.check_insert ( current_id store.docs.id%TYPE ) RETURNERAR boolean AS $$
DECLARERA
curr_role_id integer ;
BĂRJA
--DBA kan alltid lÀgga till en rad
IF SESSION_USER = 'curr_dba'
DĂ
RETURERA TRUE ;
SLUTA ;
--------------------------------
--HÀmta id för nuvarande anvÀndarroll
VĂLJ
service_functions.current_rid()
IN
curr_role_id ;
--------------------------------
--Om rollen tillÄter att skapa ett nytt dokument
--tillÄt
IF curr_role_id = 3 ELLER curr_role_id = 5
DĂ
RETURERA TRUE ;
SLUTA ;
--------------------------------
RETURERA FALSE ;
SLUTA
$$ SPRĂ
K plpgsql SECURITY DEFINER;
ALTERERA FUNKTION store.check_insert( store.docs.id%TYPE ) ĂGARE TILL store ;
Ă
TERKALLA UTFĂRANDE PĂ
FUNKTION store.check_insert( store.docs.id%TYPE ) FRĂ
N public;
BEVAKA UTFĂRANDE PĂ
FUNKTION store.check_insert( store.docs.id%TYPE ) TILL service_functions;
Kontrollera möjligheten att utföra DELETE av en rad
check_delete
SKAPA ELLER ERSĂTT FUNKTION store.check_delete ( current_id store.docs.id%TYPE )
RETURNERAR boolean AS $$
BĂRJA
--Endast DBA kan ta bort en rad
IF SESSION_USER = 'curr_dba'
DĂ
RETURERA TRUE ;
SLUTA ;
--------------------------------
RETURERA FALSE ;
SLUTA
$$ SPRĂ
K plpgsql
SECURITY DEFINER;
ALTERERA FUNKTION store.check_delete( store.docs.id%TYPE ) ĂGARE TILL store ;
Ă
TERKALLA UTFĂRANDE PĂ
FUNKTION store.check_delete( store.docs.id%TYPE ) FRĂ
N public;Kontrollera möjligheten att utföra UPDATE av en rad.
uppdatera_anvÀnder
SKAPA ELLER ERSĂTT FUNKTION store.update_using ( current_id store.docs.id%TYPE , is_del boolean )
RETURNS boolean SOM $$
BĂRJA
--Dokumenten med status 'borttagen' - kan inte redigeras
OM is_del
DĂ
RETURN FALSE ;
ANNARS
RETURN TRUE ;
SLUT OM ;
SLUT
$$ SPRĂ
K plpgsql SĂKERHETSFĂRDELARE;
ALTER FUNKTION store.update_using( store.docs.id%TYPE , boolean ) ĂGARE TILL store ;
Ă
TERKALLA KĂRNING PĂ
FUNKTION store.update_using( store.docs.id%TYPE , boolean ) FRĂ
N offentlig;
GE KĂRNING PĂ
FUNKTION store.update_using( store.docs.id%TYPE ) TILL service_functions;uppdatera_kontroll
SKAPA ELLER ERSĂTT FUNKTION store.update_with_check ( current_id store.docs.id%TYPE , is_del boolean )
RETURNS boolean SOM $$
DEKLARERA
current_rid heltal ;
current_statid heltal ;
BĂRJA
--DBA kan visa raden
OM SESSION_USER = 'curr_dba'
DĂ
RETURN TRUE ;
SLUT OM ;
--------------------------------
--HÀmta id för rollen för den aktuella anvÀndaren
VĂLJ
service_functions.current_rid()
IN
curr_role_id ;
--------------------------------
--Borttagning av dokument - Àndra indikeringsflagga
OM is_deleted
DĂ
--Om anvÀndarrollen ***
OM current_role_id = 3
DĂ
VĂLJ
stat_id
IN
curr_statid
FRĂ
N
store.docs
VARFĂR
id = current_id ;
--Dokument i status *** kan inte tas bort
OM current_status_id = 11
DĂ
RETURN FALSE ;
ANNARS
--Kan ta bort dokument i andra statusar
RETURN TRUE ;
SLUT OM ;
--Annars, om anvÀndarrollen ***
ELSIF current_role_id = 5
DĂ
--Alla dokumentstatusar
RETURN TRUE ;
ANNARS
--Andra anvÀndare kan inte ta bort dokument
RETURN FALSE ;
SLUT OM ;
ANNARS
--Uppdatering av dokumentet Àr tillÄten
RETURN TRUE ;
SLUT OM ;
RETURN FALSE ;
SLUT
$$ SPRĂ
K plpgsql SĂKERHETSFĂRDELARE;
ALTER FUNKTION store.update_with_check( store.docs.id%TYPE , boolean ) ĂGARE TILL store ;
Ă
TERKALLA KĂRNING PĂ
FUNKTION store.update_with_check( store.docs.id%TYPE , boolean ) FRĂ
N offentlig;
GE KĂRNING PĂ
FUNKTION store.update_with_check( store.docs.id%TYPE ) TILL service_functions;Aktivera politiken för radnivÄsÀkerhet för tabellen.
AKTIVERA RADNIVĂ SĂKERHET
ALTER TABELL store.docs AKTIVERA RADNIVĂ
SĂKERHET ;
SKAPA POLICY doc_select PĂ
store.docs FĂR SELECT TILL service_functions ANVĂND ( (VĂLJ store.check_select(id)) );
SKAPA POLICY doc_insert PĂ
store.docs FĂR INSERT TILL service_functions MED KONTROLL ( (VĂLJ store.check_insert(id)) );
SKAPA POLICY docs_delete PĂ
store.docs FĂR DELETE TILL service_functions ANVĂND ( (VĂLJ store.check_delete(id)) );
SKAPA POLICY doc_update_using PĂ
store.docs FĂR UPDATE TILL service_functions ANVĂND ( (VĂLJ store.update_using(id , is_del )) );
SKAPA POLICY doc_update_check PĂ
store.docs FĂR UPDATE TILL service_functions MED KONTROLL ( (VĂLJ store.update_with_check(id , is_del )) );Resultat
Det fungerar.
Den föreslagna strategin möjliggjorde överföringen av implementeringen av rollmodellen frÄn affÀrsfunktionsnivÄn till datalagringsnivÄn.
Funktioner kan anvÀndas som mall för att implementera mer avancerade modeller för dataskydd, om affÀrskraven krÀver det.
KĂ€lla: habr.com
