Zbatimi i modelit të roleve të aksesit duke përdorur Row Level Security në PostgreSQL

Zhvillimi i temës Artikull mbi zbatimin e Row Level Security në PostgreSQL dhe për një përgjigje të zgjeruar në koment.

Strategjia e pĂ«rdorur pĂ«rfshin konceptin e "LogjikĂ«s sĂ« biznesit nĂ« DB", e cila Ă«shtĂ« pĂ«rshkruar mĂ« nĂ« detaje kĂ«tu — Artikull mbi zbatimin e logjikĂ«s sĂ« biznesit nĂ« nivelin e funksioneve tĂ« ruajtura PostgreSQL

Pjesa teorike Ă«shtĂ« pĂ«rshkruar shkĂ«lqyeshĂ«m nĂ« dokumentacion Postgres Pro — Politikat e mbrojtjes sĂ« rreshtave. MĂ« poshtĂ« Ă«shtĂ« analizuar implementimi praktik i njĂ« detyre tĂ« caktuar tĂ« biznesit — modeli i rolit tĂ« qasjes nĂ« tĂ« dhĂ«na.

Zbatimi i modelit të roleve të aksesit duke përdorur Row Level Security në PostgreSQL

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

Formulimi i detyrës

Duhet të kufizohet qasja për shikim/inserim/modifikim/zhdukje të dokumentit në përputhje me rolin e përdoruesit të aplikacionit. Nën rol nënkuptohet një regjistrim në tabelën roles e lidhur me marrëdhënien shumë-më-shumë me tabelën users. Detajet e implementimit të tabelave, për shkak të triviales, janë lënë jashtë. Gjithashtu janë lënë jashtë detajet specifike të implementimit të lidhura me fushën tematike.

Implementimi

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 implementimin e RLS

Kontrolli i mundësisë për të ekzekutuar SELECT për rreshtin

check_select

KRIJONI O RINOVONI FUNKSIONIN store.check_select ( current_id store.docs.id%TYPE ) KTHEN ROLLI BOOLEAN SI $$ DECLARONI rezultatin BOOLEAN ; curr_pid INTEGER ; curr_stat_id INTEGER ; doc_man_id INTEGER ; FILLIMI KRIJONI -- DBA ka qasje nĂ« tĂ« gjithĂ« dokumentet IF SESSION_USER = 'curr_dba' THEN KTHEN TRUE ; END IF ; -------------------------------- -- NĂ«se dokumenti ka etiketĂ«n 'tĂ« fshirĂ«' - mos e shfaq nĂ« seleksionin SELECT is_del INTO rezultatin FROM store.docs WHERE id = current_id ; IF rezultati = TRUE THEN KTHEN 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Ă« i emĂ«ruar - shtoni dokumentin nĂ« seleksion IF doc_man_id != curr_pid OR doc_man_id IS NULL THEN KTHEN TRUE ; ELSE -- Merrni statusin aktual tĂ« dokumentit SELECT stat_id INTO curr_statid FROM store.docs WHERE id = current_id ; -- NĂ«se statusi lejon qĂ« dokumenti tĂ« shikohet - shtoni dokumentin nĂ« seleksion IF curr_statid = 4 OR curr_statid = 9 THEN KTHEN TRUE ; ELSE -- NĂ« tĂ« kundĂ«rt - pĂ«rjashtoni dokumentin nga seleksioni KTHEN FALSE ; END IF ; END IF ; -------------------------------- KTHEN FALSE ; END $$ GJUHA plpgsql DEFINUES I SIGURISË; ZËVENDËSO FUNKSIONIN store.check_select( store.docs.id%TYPE ) PRONAR TE store ; REVOKO EKZEKUTIMIN NË FUNKSIONIN store.check_select( store.docs.id%TYPE ) NGA publik; GRANT EKZEKUTIMIN NË FUNKSIONIN store.check_select( store.docs.id%TYPE ) TE shĂ«rbimeve funksionale; 

Kontrolli i mundësisë për të kryer INSERT të rreshtit

kontrollo_insert

KRIJONI O RINOVONI FUNKSIONIN store.check_insert ( current_id store.docs.id%TYPE ) KTHEN ROLLI BOOLEAN SI $$ DECLARONI curr_role_id INTEGER ; FILLIMI KRIJONI -- DBA mund tĂ« shtojĂ« rreshtin nĂ« çdo rast IF SESSION_USER = 'curr_dba' THEN KTHEN TRUE ; END IF ; -------------------------------- -- Merrni id e rolit tĂ« pĂ«rdoruesit aktual SELECT service_functions.current_rid() INTO curr_role_id ; -------------------------------- -- NĂ«se roli lejon mundĂ«sinĂ« pĂ«r tĂ« krijuar njĂ« dokument tĂ« ri -- lejohet IF curr_role_id = 3 OR curr_role_id = 5 THEN KTHEN TRUE ; END IF ; -------------------------------- KTHEN FALSE ; END $$ GJUHA plpgsql DEFINUES I SIGURISË; ZËVENDËSO FUNKSIONIN store.check_insert( store.docs.id%TYPE ) PRONAR TE store ; REVOKO EKZEKUTIMIN NË FUNKSIONIN store.check_insert( store.docs.id%TYPE ) NGA publik; GRANT EKZEKUTIMIN NË FUNKSIONIN store.check_insert( store.docs.id%TYPE ) TE shĂ«rbimeve funksionale; 

Kontrolli i mundësisë për të kryer DELETE të rreshtit

kontrollo_fshij

KRIJONI O RINOVONI FUNKSIONIN store.check_delete ( current_id store.docs.id%TYPE ) KTHEN ROLLI BOOLEAN SI $$ FILLIMI -- VetĂ«m DBA mund tĂ« fshijĂ« rreshtin IF SESSION_USER = 'curr_dba' THEN KTHEN TRUE ; END IF ; -------------------------------- KTHEN FALSE ; END $$ GJUHA plpgsql DEFINUES I SIGURISË; ZËVENDËSO FUNKSIONIN store.check_delete( store.docs.id%TYPE ) PRONAR TE store ; REVOKO EKZEKUTIMIN NË FUNKSIONIN store.check_delete( store.docs.id%TYPE ) NGA publik;

Kontrolli i mundësisë për të kryer UPDATE të rreshtit.

përdorimi_aktualizimi

KRIJO OSE ZËVENDOS FUNKSIONIN store.pĂ«rdorimi_aktualizimi (current_id store.docs.id%TYPE, is_del boolean)
KTHEN BOOLEAN AS $$
FILLIMI
   --Dokumentet me statusin 'të fshirë' nuk redaktohen
   NËSE is_del
   ATËHERË
     KTHIM FALSE;
 ELSE
    KTHIM TRUE;
  FUND IF;

FUND
$$ GJUHË plpgsql SIGURIA DEFINER;
NDYSHO FUNKSIONIN store.përdorimi_aktualizimi (store.docs.id%TYPE, boolean) PRONAR TE store;
HEQ EKZEKUTIMIN NË FUNKSIONIN store.pĂ«rdorimi_aktualizimi (store.docs.id%TYPE, boolean) NGA publik;
JEP EKZEKUTIMIN NË FUNKSIONIN store.pĂ«rdorimi_aktualizimi (store.docs.id%TYPE) TE funksionet_e_shĂ«rbimeve;

kontrolli_aktualizimit

KRIJO OSE ZËVENDOS FUNKSIONIN store.aktualizimi_me_kontroll (current_id store.docs.id%TYPE, is_del boolean)
KTHEN BOOLEAN AS $$
DECLARE
  current_rid integer;
  current_statid integer;
FILLIMI

  --DBA mund të shikojë rreshtin
  NËSE USER_SESSION = 'curr_dba'
  ATËHERË
    KTHIM TRUE;
  FUND IF;
  --------------------------------

 --Merr id-në e rolit të përdoruesit aktual
 SELECT
   funksionet_e_shërbimeve.current_rid()
  NË
    curr_role_id;
 --------------------------------                            

 --Fshirja e dokumentit - ndryshimi i shenjës
 NËSE is_deleted
 ATËHERË
   --Nëse roli i përdoruesit ***
   NËSE current_role_id = 3
   ATËHERË
      SELECT
        stat_id
      NË
        curr_statid
      NGA
        store.docs
      KU
        id = current_id;

      --Dokumenti në statusin *** nuk mund të fshihet
      NËSE current_status_id = 11
      ATËHERË
         KTHIM FALSE;
      ELSE
      --Mund të fshihet dokumenti në statuset e tjera
        KTHIM TRUE;
      FUND IF;

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

KTHIM FALSE;
FUND
$$ GJUHË plpgsql SIGURIA DEFINER;
NDYSHO FUNKSIONIN store.aktualizimi_me_kontroll (storg.docs.id%TYPE, boolean) PRONAR TE store;
HEQ EKZEKUTIMIN NË FUNKSIONIN store.aktualizimi_me_kontroll (storg.docs.id%TYPE, boolean) NGA publik;
JEP EKZEKUTIMIN NË FUNKSIONIN store.aktualizimi_me_kontroll (store.docs.id%TYPE) TE funksionet_e_shĂ«rbimeve;

Aktivizimi i politikës së Sigurisë së Nivelit të Rreshtit për tabelën.

AKTIVIZO SIGURINË E NIVELIT TË RRESHTIT

NDYSHO TABELËN store.docs AKTIVIZO SIGURINË E NIVELIT TË RRESHTIT;

KRIJO POLITIKËN doc_select NË store.docs PËR ZGJEDHJE TE funksionet_e_shĂ«rbimeve PËR MBULIM (SELECT store.check_select(id));
KRIJO POLITIKËN doc_insert NË store.docs PËR SHTIM TE funksionet_e_shĂ«rbimeve ME KONTROLL (SELECT store.check_insert(id));
KRIJO POLITIKËN docs_delete NË store.docs PËR FSHIRJE TE funksionet_e_shĂ«rbimeve PËR MBULIM (SELECT store.check_delete(id));

KRIJO POLITIKËN doc_update_using NË store.docs PËR PËRDITËSIM TE funksionet_e_shĂ«rbimeve PËR MBULIM (SELECT store.pĂ«rdorimi_aktualizimi(id, is_del));
KRIJO POLITIKËN doc_update_check NË store.docs PËR PËRDITËSIM TE funksionet_e_shĂ«rbimeve ME KONTROLL (SELECT store.aktualizimi_me_kontroll(id, is_del));

Përfundimi

Kjo funksionon.

Strategjia e propozuar lejoj transferimin e realizimit 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ë shabllon për realizimin e modele më të sofistikuara të fshehjes së të dhënave, nëse kërkesat e biznesit e kërkojnë këtë.

Burimi: habr.com

Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster