مطالعه ای در مورد پیاده سازی امنیت سطح ردیف در 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)

چیزی که در بیان مسئله مورد نیاز بود.

مجموع

اگر موضوع جالب است، در مطالعه بعدی می توانید نمونه ای از پیاده سازی یک مدل مبتنی بر نقش برای جداسازی دسترسی داده ها با استفاده از Row Level Security را نشان دهید.

منبع: www.habr.com

اضافه کردن نظر