Pētījums par rindas līmeņa drošības ieviešanu PostgreSQL

Kā papildinājums Pētījums par biznesa loģikas ieviešanu PostgreSQL saglabāto funkciju līmenī и galvenokārt, lai iegūtu detalizētu atbildi par komentārs.

Teorētiskā daļa ir labi aprakstīta dokumentācijā PostgreSQL Sākot no Rindu aizsardzības politikas. Zemāk ir neliela praktiska īstenošana konkrēts biznesa uzdevums - izdzēsto datu slēpšana. Īstenošanai veltīta skice Lomu modelēšana, izmantojot RLS uzrādīts atsevišķi.

Pētījums par rindas līmeņa drošības ieviešanu PostgreSQL

Rakstā nav nekā jauna, nav slēptas nozīmes vai slepenas zināšanas. Tikai skice par teorētiskās idejas praktisko realizāciju. Ja kādam interesē, izlasiet. Ja jūs neinteresē, netērējiet savu laiku.

Problēmas paziņojums

Īsi neiedziļinoties tematiskajā jomā, problēmu var formulēt šādi: Ir tabula, kas īsteno noteiktu uzņēmējdarbības vienību. Tabulas rindas var dzēst, bet rindas nevar fiziski dzēst, tām jābūt paslēptām.

Jo ir teikts: “Neko neizdzēsiet, vienkārši pārdēvējiet to. Internets uzglabā VISU"

Pa ceļam nav ieteicams pārrakstīt esošās saglabātās funkcijas, kas darbojas ar šo entītiju.

Lai īstenotu šo koncepciju, tabulā ir atribūts ir_dzēsts. Tad viss ir vienkārši – jāpārliecinās, ka klients redz tikai tās rindas, kurās atribūts ir_dzēsts viltus Kam tiek izmantots mehānisms? Rindas līmeņa drošība.

Ieviešana

Izveidojiet atsevišķu lomu un shēmu

CREATE ROLE repos;
CREATE SCHEMA repos;

Izveidojiet mērķa tabulu

CREATE TABLE repos.file
(
...
is_del BOOLEAN DEFAULT FALSE
);
CREATE SCHEMA repos

Ieslēdziet Rindas līmeņa drošība

ALTER TABLE repos.file  ENABLE ROW LEVEL SECURITY ;
CREATE POLICY file_invisible_deleted  ON repos.file FOR ALL TO dba_role USING ( NOT is_deleted );
GRANT ALL ON TABLE repos.file to dba_role ;
GRANT USAGE ON SCHEMA repos TO dba_role ;

Servisa funkcija — tabulas rindas dzēšana

CREATE OR REPLACE repos.delete( curr_id repos.file.id%TYPE)
RETURNS integer AS $$
BEGIN
...
UPDATE repos.file
SET is_del = TRUE 
WHERE id = curr_id ; 
...
END
$$ LANGUAGE plpgsql SECURITY DEFINER;

Biznesa funkcija — dokumenta dzēšana

CREATE OR REPLACE business_functions.deleteDoc( doc_for_delete JSON )
RETURNS JSON AS $$
BEGIN
...
PERFORM  repos.delete( doc_id ) ;
...
END
$$ LANGUAGE plpgsql SECURITY DEFINER;

rezultātus

Klients izdzēš dokumentu

SELECT business_functions.delCFile( (SELECT json_build_object( 'CId', 3 )) );

Pēc dzēšanas klients dokumentu neredz

SELECT business_functions.getCFile"( (SELECT json_build_object( 'CId', 3 )) ) ;
-----------------
(0 rows)

Bet datubāzē dokuments netiek dzēsts, tiek mainīts tikai atribūts ir_del

psql -d my_db
SELECT  id, name , is_del FROM repos.file ;
id |  name  | is_del
--+---------+------------
 1 |  test_1 | t
(1 row)

Tas ir tas, kas tika prasīts problēmas paziņojumā.

Kopsavilkums

Ja tēma ir interesanta, nākamajā pētījumā varat parādīt piemēru par lomām balstīta modeļa ieviešanu datu piekļuves atdalīšanai, izmantojot rindas līmeņa drošību.

Avots: www.habr.com

Pievieno komentāru