Rollimudeli juurdepÀÀsu rakendamine Row Level Security kasutamisega PostgreSQLis.

Teema arendamine EtĂŒĂŒd PostgreSQL-i ridade taseme turvameetmete rakendamisest ja laiendatud vastuse jaoks . Tundub, et kommentaar.

Kasutatud strateegia eeldab kontseptsiooni "Äriloogika andmebaasis", mida on veidi lĂ€hemalt kirjeldatud siin — EtĂŒĂŒd Ă€riloogika rakendamisest PostgreSQL-i salvestatud protseduuride tasandil

Teoreetiline osa on dokumentatsioonis suurepĂ€raselt kirjeldatud Postgres Pro — Ridade kaitse poliitikad. Allpool kĂ€sitletakse konkreetse rakendamise praktikat konkreetse Ă€riĂŒlesande — andmete juurdepÀÀsu rollimudeli.

Rollimudeli juurdepÀÀsu rakendamine Row Level Security kasutamisega PostgreSQLis.

Artiklis ei ole midagi uut, pole peidetud tÀhendust ega saladusi. Lihtsalt visand teoreetilise idee praktilisest rakendamisest. Kui see huvitab, lugege. Kui ei, siis Àrge raisake oma aega.

Ülesande seadmine

On vajalik piirata juurdepÀÀsu dokumendi vaatamiseks/sisestamiseks/muutmiseks/kustutamiseks vastavalt rakenduse kasutaja rollile. Rolli all mĂ”istetakse kirjet tabelis roles paljusid-mitme suhetega tabeliga users. Tabelite rakenduse ĂŒksikasjad, lihtsuse tĂ”ttu, jĂ€etakse vĂ€lja. Samuti jĂ€etakse vĂ€lja spetsiifilised rakenduse detailid, mis on seotud ainevaldkonnaga.

Rakendamine

Loome rollid, skeemid, tabeli

Andmebaasi objektide loomine

CREATE ROLE store;
CREATE SCHEMA store AUTHORIZATION store;
CREATE TABLE store.docs
(
  id integer ,         --dokumendi id
  man_id integer , --dokumendi halduri id
  stat_id integer ,  --dokumendi staatuse id
  ...
  is_del BOOLEAN DEFAULT FALSE 
);
ALTER TABLE store.docs ADD CONSTRAINT doc_pk PRIMARY KEY (id);
ALTER TABLE store.docs OWNER TO store ;

Loome funktsioonid RLS rakendamiseks

Kontrolli, kas saab SELECT rida teostada

check_select

Loo ja asenda funktsioon store.check_select ( current_id store.docs.id%TYPE ) RETURNS boolean AS $$
DECLARE
  result boolean ;
  curr_pid integer ;
  curr_stat_id integer ;
  doc_man_id integer ;
BEGIN 
  -- DBA-l on juurdepÀÀs kÔigile dokumentidele
  IF SESSION_USER = 'curr_dba'
  THEN
    RETURN TRUE ;
  END IF ;
  --------------------------------

  -- Kui dokument on mÀrgistatud 'kustutatud', siis ei nÀidata seda valikus
  SELECT
    is_del
  INTO
    result
  FROM
    store.docs
  WHERE
    id = current_id ;
 IF result = TRUE
 THEN
   RETURN FALSE ;
 END IF ;
 --------------------------------

 -- Saada praeguse kasutaja id
 SELECT
   service_function.get_curr_pid ()
 INTO
   curr_pid ;
 --------------------------------

 -- Saada dokumendi halduri id
 SELECT
   man_id
 INTO
   doc_man_id
 FROM
   store.docs
 WHERE
   id = current_id ;
 --------------------------------

 -- Kui dokumendi haldur ei ole praegune kasutaja vÔi haldurit ei ole mÀÀratud
 -- lisa dokument valikusse
 IF doc_man_id != curr_pid OR doc_man_id IS NULL
 THEN
   RETURN TRUE  ;
 ELSE
   -- Saada dokumendi praegune staatus
   SELECT
     stat_id                                         
   INTO
     curr_statid
   FROM
     store.docs
   WHERE
     id = current_id ;
    
   -- Kui staatus lubab dokumenti vaadata - lisa dokument valikusse                     
   IF curr_statid = 4 OR curr_statid = 9
   THEN
     RETURN TRUE ;
   ELSE
   -- Muidu - vÀlista dokument valikust
     RETURN FALSE ;
    END IF ;
  END IF ;
  --------------------------------

 RETURN FALSE ;
END
$$ LANGUAGE plpgsql SECURITY DEFINER;
ALTER FUNCTION store.check_select( store.docs.id%TYPE  ) OWNER TO store ;
REVOKE EXECUTE ON FUNCTION store.check_select( store.docs.id%TYPE  ) FROM public; 
GRANT EXECUTE ON FUNCTION store.check_select( store.docs.id%TYPE  ) TO service_functions; 

Kontrolli, kas rida on vÔimalik sisestada

check_insert

Loo ja asenda funktsioon store.check_insert ( current_id store.docs.id%TYPE ) RETURNS boolean AS $$
DECLARE
  curr_role_id integer ;
BEGIN
  -- DBA vÔib rida igal juhul lisada
  IF SESSION_USER = 'curr_dba'
  THEN
    RETURN TRUE ;
  END IF ;
  --------------------------------

 -- Saada praeguse kasutaja rolli id 
 SELECT
   service_functions.current_rid()
  INTO
    curr_role_id ;
 --------------------------------

-- Kui roll vÔimaldab uue dokumendi loomist
-- luba
IF curr_role_id = 3 OR curr_role_id = 5     
THEN
  RETURN TRUE ;
END IF ;
--------------------------------
RETURN FALSE  ;
END
$$ LANGUAGE plpgsql SECURITY DEFINER;
ALTER FUNCTION store.check_insert( store.docs.id%TYPE  ) OWNER TO store ;
REVOKE EXECUTE ON FUNCTION store.check_insert( store.docs.id%TYPE  ) FROM public;
GRANT EXECUTE ON FUNCTION store.check_insert( store.docs.id%TYPE  ) TO service_functions; 

Kontrolli, kas rida on vÔimalik kustutada

check_delete

Loo ja asenda funktsioon store.check_delete ( current_id store.docs.id%TYPE )
RETURNS boolean AS $$
BEGIN  
  -- Ainult DBA vÔib rida kustutada 
  IF SESSION_USER = 'curr_dba'
  THEN
    RETURN TRUE ;
  END IF ;
  --------------------------------

  RETURN FALSE ;
END
$$ LANGUAGE plpgsql
SECURITY DEFINER;
ALTER FUNCTION store.check_delete( store.docs.id%TYPE  ) OWNER TO store ;
REVOKE EXECUTE ON FUNCTION store.check_delete( store.docs.id%TYPE  ) FROM public;

Kontrolli, kas rida on vÔimalik uuendada.

update_using

Looja vÔi asenda funktsioon store.update_using ( current_id store.docs.id%TYPE , is_del boolean )
TULEMUSED boolean NAGU $$
ALUSTA  
   --Dokumendid, millel on olek 'kustutatud' - ei redigeerita
   KUI is_del 
   SEE
     TAGASTA FALSE ;
 MUU
    TAGASTA TRUE ;
  LÕPETA

LÕPETA
$$ KEEL plpgsql SECURITY DEFINER;
MUUDA FUNKTSIOON store.update_using( store.docs.id%TYPE , boolean ) OMANIK KAUPO ;
TÜHISTA EXECUTE FUNKTSIOONIL store.update_using( store.docs.id%TYPE , boolean ) PUBLIC;
ANDA EXECUTE FUNKTSIOONILE store.update_using( store.docs.id%TYPE ) SERVICE_FUNCTIONS;

update_check

Looja vÔi asenda funktsioon store.update_with_check ( current_id store.docs.id%TYPE , is_del boolean )
TULEMUSED boolean NAGU $$
DECLARE
  current_rid integer ;
  current_statid integer ;
ALUSTA                

  --DBA saab vaadata rida 
  KUI SESSION_USER = 'curr_dba'
  SEE
    TAGASTA TRUE ;
  LÕPETA
  --------------------------------

 --Hangi praegune kasutaja rolli id 
 VALI
   service_functions.current_rid()
  INTO
    curr_role_id ;
 --------------------------------                            

 --Dokumendi kustutamine - seisundi muutmine 
 KUI is_deleted
 SEE
   --Kui kasutaja roll ***
   KUI current_role_id = 3        
   SEE
      VALI
        stat_id                                          
      INTO
        curr_statid
      FROM
        store.docs
      KUS
        id = current_id ;

      --Dokument olekus *** ei saa kustutada 
      KUI current_status_id = 11
      SEE
         TAGASTA FALSE ;
      MUU
      --Dokumente saab kustutada teistes olekutes
        TAGASTA TRUE ;
      LÕPETA

    --Vastasel juhul, kui kasutaja roll ***
    ELSIF current_role_id = 5            
    SEE
      --KÔik dokumentide olekud 
      TAGASTA TRUE ;
    MUU
      --Teised kasutajad ei saa dokumente kustutada
      TAGASTA FALSE ;
    LÕPETA
 ELSE      
   --Dokumendi uuendamine on lubatud
    TAGASTA TRUE ;
LÕPETA

TAGASTA FALSE ;
LÕPETA
$$ KEEL plpgsql SECURITY DEFINER;
MUUDA FUNKTSIOON store.update_with_check( storg.docs.id%TYPE ,  boolean ) OMANIK KAUPO ;
TÜHISTA EXECUTE FUNKTSIOONIL store.update_with_check( storg.docs.id%TYPE ,  boolean )  PUBLIC;
ANDA EXECUTE FUNKTSIOONILE store.update_with_check( store.docs.id%TYPE ) SERVICE_FUNCTIONS;

Ridade tasandi turbe poliitika sisselĂŒlitamine tabelis.

LUBA RIDADE TASANDI TURVE

MUUDA TABELIT store.docs LUBA RIDADE TASANDI TURVE ;

LOO POLIITIKA doc_select STORE.docs VALIKU KAUPO service_functions KASUTADES ( (VALI store.check_select(id)) );
LOO POLIITIKA doc_insert STORE.docs INSERT KAUPO service_functions KONTROLLIDE ( (VALI store.check_insert(id)) );
LOO POLIITIKA docs_delete STORE.docs KUSTUTAMINE KAUPO service_functions KASUTADES ( (VALI store.check_delete(id)) );

LOO POLIITIKA doc_update_using STORE.docs UUENDAMINE KAUPO service_functions KASUTADES ( (VALI store.update_using(id , is_del )) );
LOO POLIITIKA doc_update_check STORE.docs UUENDAMINE KAUPO service_functions KONTROLLIDE ( (VALI store.update_with_check(id , is_del )) );

KokkuvÔte

See töötab.

Ettepanekute strateegia vÔimaldas edastada rollimudeli teostamise tasemelt Àrifunktsioonide tasemele andmehÔive tasemele.

Funktsioone saab kasutada ƥabloonina keerukamate andmete varjamise mudelite rakendamiseks, kui Àri nÔuded seda nÔuavad.

Allikas: habr.com

Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster