Μια μελέτη για την εφαρμογή της ασφάλειας σε επίπεδο γραμμής στην PostgreSQL

Ως συμπλήρωμα του Μια μελέτη για την εφαρμογή της επιχειρηματικής λογικής σε επίπεδο αποθηκευμένων συναρτήσεων PostgreSQL и κυρίως για μια λεπτομερή απάντηση επί σχόλιο.

Το θεωρητικό μέρος περιγράφεται καλά στην τεκμηρίωση PostgreSQL - Πολιτικές προστασίας σειρών. Παρακάτω είναι μια πρακτική εφαρμογή ενός μικρού συγκεκριμένη επιχειρηματική εργασία - απόκρυψη διαγραμμένων δεδομένων. Σκίτσο αφιερωμένο στην υλοποίηση Μοντελοποίηση ρόλων με χρήση RLS παρουσιάζονται χωριστά.

Μια μελέτη για την εφαρμογή της ασφάλειας σε επίπεδο γραμμής στην PostgreSQL

Δεν υπάρχει τίποτα νέο στο άρθρο, δεν υπάρχει κρυφό νόημα ή μυστική γνώση. Απλά ένα σκίτσο για την πρακτική εφαρμογή μιας θεωρητικής ιδέας. Αν κάποιος ενδιαφέρεται ας το διαβάσει. Αν δεν σας ενδιαφέρει, μην χάνετε το χρόνο σας.

Δήλωση προβλήματος

Χωρίς να βουτήξουμε βαθιά στη θεματική περιοχή, εν συντομία, το πρόβλημα μπορεί να διατυπωθεί ως εξής: Υπάρχει ένας πίνακας που υλοποιεί μια συγκεκριμένη επιχειρηματική οντότητα. Οι σειρές στον πίνακα μπορούν να διαγραφούν, αλλά οι σειρές δεν μπορούν να διαγραφούν φυσικά, πρέπει να είναι κρυφές.

Διότι λέγεται: «Μην διαγράψετε τίποτα, απλώς μετονομάστε το. Το Διαδίκτυο αποθηκεύει ΤΑ ΠΑΝΤΑ»

Στην πορεία, συνιστάται να μην ξαναγράψετε υπάρχουσες αποθηκευμένες συναρτήσεις που λειτουργούν με αυτήν την οντότητα.

Για την υλοποίηση αυτής της έννοιας, ο πίνακας έχει το χαρακτηριστικό is_deleted. Στη συνέχεια, όλα είναι απλά - πρέπει να βεβαιωθείτε ότι ο πελάτης μπορεί να δει μόνο τις γραμμές στις οποίες το χαρακτηριστικό is_deleted ψευδής Σε τι χρησιμεύει ο μηχανισμός; Ασφάλεια επιπέδου σειράς.

Реализация

Δημιουργήστε ξεχωριστό ρόλο και σχήμα

CREATE ROLE repos;
CREATE SCHEMA repos;

Δημιουργήστε τον πίνακα στόχο

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

Ανάβω Ασφάλεια επιπέδου σειράς

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 ;

Λειτουργία σέρβις — διαγραφή μιας σειράς στον πίνακα

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;

Επιχειρηματική λειτουργία — διαγραφή εγγράφου

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

Ευρήματα

Ο πελάτης διαγράφει το έγγραφο

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

Μετά τη διαγραφή, ο πελάτης δεν βλέπει το έγγραφο

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

Αλλά στη βάση δεδομένων το έγγραφο δεν διαγράφεται, αλλά αλλάζει μόνο το χαρακτηριστικό is_del

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

Αυτό που απαιτούνταν στη δήλωση προβλήματος.

Σύνολο

Εάν το θέμα είναι ενδιαφέρον, στην επόμενη μελέτη μπορείτε να δείξετε ένα παράδειγμα εφαρμογής ενός μοντέλου βασισμένου σε ρόλους για τον διαχωρισμό της πρόσβασης δεδομένων χρησιμοποιώντας την ασφάλεια επιπέδου γραμμής.

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο