Implementimi i modelit të rolit për aksesin duke përdorur Sigurinë në Nivelin e Rreshtave në PostgreSQL

Zhvillimi i temës Studimi mbi implementimin e Sigurisë në Nivelin e Rreshtit në PostgreSQL dhe për një përgjigje të hollësishme në koment.

Strategjia e pĂ«rdorur nĂ«nkupton pĂ«rdorimin e konceptit "Logjika e biznesit nĂ« DB", e cila Ă«shtĂ« shpjeguar pak mĂ« gjerĂ« kĂ«tu — Studimi mbi realizimin e logjikĂ«s sĂ« biznesit nĂ« nivelin e funksioneve tĂ« pagabueshme PostgreSQL

Pjesa teorike Ă«shtĂ« e shkruar shumĂ« mirĂ« nĂ« dokumentacion Postgres Pro — Politikat e mbrojtjes sĂ« rreshtave. MĂ« poshtĂ« shikohet realizimi praktik i njĂ« problemi konkret tĂ« biznesit — modeli i rolit tĂ« aksesit nĂ« tĂ« dhĂ«na.

Implementimi i modelit të rolit për aksesin duke përdorur Sigurinë në Nivelin e Rreshtave në PostgreSQL

NĂ« artikull nuk ka asgjĂ« tĂ« re, nuk ka kuptim tĂ« fshehur dhe njohuri sekrete. Thjesht njĂ« skicĂ« mbi realizimin praktik tĂ« njĂ« ideje teorike. NĂ«se dikujt i intereson — lexoni. NĂ«se nuk intereson — mos e humbni kohĂ«n tuaj kot.

Vendosja e detyrës

Duhet të ndahen qasjet për shikimin / futjen / ndryshimin / fshirjen e dokumentit në përputhje me rolit të përdoruesit të aplikacionit. Nga roli nënkuptohet një regjistër në tabelën roles e cila ka një lidhje shumë-te-many me tabelën përdoruesit. Detajet e realizimit të tabelave, për shkak të thjeshtësisë, janë lënë mënjanë. Gjithashtu janë lënë jashtë detajet e sakta të realizimit që lidhen me fushën e subjektit.

Realizimi

Krijojmë Role, Skema, Tabelën

Krijimi i objekteve të DB

CREATE ROLE store;
CREATE SCHEMA store AUTHORIZATION store;
CREATE TABLE store.docs
(
  id integer ,         --id i dokumentit
  man_id integer , --id i menaxherit të dokumentit
  stat_id integer ,  --id i statusit të dokumentit
  ...
  is_del BOOLEAN DEFAULT FALSE 
);
ALTER TABLE store.docs ADD CONSTRAINT doc_pk PRIMARY KEY (id);
ALTER TABLE store.docs OWNER TO store ;

Krijojmë funksione për realizimin e RLS

Kontrolli i mundësisë për të kryer SELECT në rresht

check_select

CREATE OR REPLACE FUNCTION 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 ka akses të gjith dokumentet
  IF SESSION_USER = 'curr_dba'
  THEN
    RETURN TRUE ;
  END IF ;
  --------------------------------

  --Nëse dokumenti ka etiketën 'i fshirë' - mos e tregoni në përzgjedhje
  SELECT
    is_del
  INTO
    result
  FROM
    store.docs
  WHERE
    id = current_id ;
 IF result = TRUE
 THEN
   RETURN FALSE ;
 END IF ;
 --------------------------------

 --Merrni id e përdoruesit aktual
 SELECT
   service_function.get_curr_pid ()
 INTO
   curr_pid ;
 --------------------------------

 --Merrni id e menaxherit të dokumentit
 SELECT
   man_id
 INTO
   doc_man_id
 FROM
   store.docs
 WHERE
   id = current_id ;
 --------------------------------

 --Nëse menaxheri i dokumentit nuk është përdoruesi aktual ose menaxheri nuk është emëruar
 --shtoni dokumentin në përzgjedhje
 IF doc_man_id != curr_pid OR doc_man_id IS NULL
 THEN
   RETURN TRUE  ;
 ELSE
   --Merrni statusin aktual të dokumentit
   SELECT
     stat_id                                         
   INTO
     curr_statid
   FROM
     store.docs
   WHERE
     id = current_id ;
    
   --Nëse statusi lejon të shikoni dokumentin - shtoni dokumentin në përzgjedhje                     
   IF curr_statid = 4 OR curr_statid = 9
   THEN
     RETURN TRUE ;
   ELSE
   --Përndryshe - përjashtoni dokumentin nga përzgjedhja
     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; 

Kontrolloni mundësinë për të kryer INSERT të një rreshti

kontrollo_insert

KRIJO OSE ZËVENDËSO FUNKSIONIN store.kontrollo_insert ( current_id store.docs.id%TYPE ) KTHEN boolean AS $$
DECLARE
  curr_role_id integer ;
BEGIN
  --DBA mund të shtojë rreshta në çdo rast
  IF SESSION_USER = 'curr_dba'
  THEN
    KTHE TRUE ;
  END IF ;
  --------------------------------

 --Merrni id-në e rolit të përdoruesit aktual
 SELECT
   service_functions.current_rid()
  INTO
    curr_role_id ;
 --------------------------------

--Nëse roli lejon krijimin e një dokumenti të ri
--lejoni
IF curr_role_id = 3 OR curr_role_id = 5     
THEN
  KTHE TRUE ;
END IF ;
--------------------------------
KTHE FALSE  ;
END
$$ GJUHA plpgsql DEFINUES I SIGURISË;
NDYSHO FUNKSIONIN store.kontrollo_insert( store.docs.id%TYPE  ) PRONARI TE store ;
HEQ EXECUTIMIN NË FUNKSIONIN store.kontrollo_insert( store.docs.id%TYPE  ) NGA publiku;
JEP EXECUTIMIN NË FUNKSIONIN store.kontrollo_insert( store.docs.id%TYPE  ) TE service_functions; 

Kontrolloni mundësinë për të kryer DELETE të një rreshti

kontrollo_fshirjen

KRIJO OSE ZËVENDËSO FUNKSIONIN store.kontrollo_fshirjen ( current_id store.docs.id%TYPE )
KTHEN boolean AS $$
BEGIN  
  --Vetëm DBA mund të fshijë një rresht 
  IF SESSION_USER = 'curr_dba'
  THEN
    KTHE TRUE ;
  END IF ;
  --------------------------------

  KTHE FALSE ;
END
$$ GJUHA plpgsql
DEFINUES I SIGURISË;
NDYSHO FUNKSIONIN store.kontrollo_fshirjen( store.docs.id%TYPE  ) PRONARI TE store ;
HEQ EXECUTIMIN NË FUNKSIONIN store.kontrollo_fshirjen( store.docs.id%TYPE  ) NGA publiku;

Kontrolloni mundësinë për të kryer UPDATE të një rreshti.

përditëso_përdorimin

CREATE OR REPLACE FUNCTION store.update_using ( current_id store.docs.id%TYPE , is_del boolean  )
RETURNS boolean AS $$
BEGIN  
   -- Dokumentet me status 'të fshirë' nuk mund të redaktohen
   IF is_del 
   THEN
     RETURN FALSE ;
 ELSE
    RETURN TRUE ;
  END IF ;

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

update_check

CREATE OR REPLACE FUNCTION store.update_with_check ( current_id store.docs.id%TYPE , is_del boolean )
RETURNS boolean AS $$
DECLARE
  current_rid integer ;
  current_statid integer ;
BEGIN                

  --DBA mund të shikojë rreshtin 
  IF SESSION_USER = 'curr_dba'
  THEN
    RETURN TRUE ;
  END IF ;
  --------------------------------

 --Merr id-në e rolit të përdoruesit aktual 
 SELECT
   service_functions.current_rid()
  INTO
    curr_role_id ;
 --------------------------------                            

 --Fshirja e dokumentit - ndryshimi i karakteristikës 
 IF is_deleted
 THEN
   --Nëse roli i përdoruesit ***
   IF current_role_id = 3        
   THEN
      SELECT
        stat_id                                          
      INTO
        curr_statid
      FROM
        store.docs
      WHERE
        id = current_id ;

      --Dokumenti në statusin *** nuk mund të fshihet 
      IF current_status_id = 11
      THEN
         RETURN FALSE ;
      ELSE
      --Mund të fshihet dokumenti në statuse të tjera
        RETURN TRUE ;
      END IF ;

    --Përndryshe, nëse roli i përdoruesit ***
    ELSIF current_role_id = 5            
    THEN
      --TĂ« gjitha statuset e dokumentit 
      RETURN TRUE ;
    ELSE
      --Përdoruesit e tjerë nuk mund të fshijnë dokumente
      RETURN FALSE ;
    END IF ;
 ELSE      
   --Përditësimi i dokumentit është i lejuar
    RETURN TRUE ;
END IF ;

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

Aktivizimi i politikës së Sigurisë në Nivelin e Rreshtit për tabelën.

AKTIVIZO SIGURISËN NË NIVELIN E RRESHTIT

ALTER TABLE store.docs AKTIVIZO SIGURISËN NË NIVELIN E RRESHTIT ;

KRIJO POLITIKË doc_select NË store.docs PËR ZGJEDHENI TE service_functions PËRDORIMI ( (ZGJEDHJE store.check_select(id)) );
KRIJO POLITIKË doc_insert NË store.docs PËR SHTIM TE service_functions ME KONTROLL ( (ZGJEDHJE store.check_insert(id)) );
KRIJO POLITIKË docs_delete NË store.docs PËR FSHIRJEN TE service_functions PËRDORIMI ( (ZGJEDHJE store.check_delete(id)) );

KRIJO POLITIKË doc_update_using NË store.docs PËR PËRDITËSIM TE service_functions PËRDORIMI ( (ZGJEDHJE store.update_using(id , is_del )) );
KRIJO POLITIKË doc_update_check NË store.docs PËR PËRDITËSIM TE service_functions ME KONTROLL ( (ZGJEDHJE store.update_with_check(id , is_del )) );

Përfundimi

Kjo funksionon.

Strategjia e propozuar lejoi transferimin e zbatimit të modelit të rolit nga niveli i funksioneve të biznesit në nivelin e ruajtjes së të dhënave.

Funksionet mund të përdoren si një model për zbatimin e modeleve më të avancuara të fshehjes së të dhënave, nëse kërkesat e biznesit e kërkojnë këtë.

Burimi: habr.com

Bli njĂ« hosting tĂ« besueshĂ«m pĂ«r faqet me mbrojtje DDoS, VPS VDS serverĂ« đŸ”„ Bli njĂ« hosting tĂ« besueshĂ«m pĂ«r faqet me mbrojtje DDoS, VPS VDS serverĂ« | ProHoster