[MemFireDB,帶你體驗不一樣的雲端飛翔。]()
RLS(ROW Level Security) 是PostgreSQL 9。5版本中新增特性,提供了基於行的安全策略,限制資料庫使用者的查看錶資料許可權。要知道在9。5版本之前,資料庫中對使用者的許可權管控在表級別,例如:限制某個使用者只能查詢某個表。採用RLS後,不同的使用者訪問一個表可以看到不同的資料。
1、概述
預設的話,表沒有任何安全策略限制。這樣使用者根據 SQL 特權系統具有對錶的訪問特權,對於查詢或更新來說其中所有的行都是平等的。當在一個表上啟用行安全性時,所有對該表選擇行或者修改行的普通訪問都必須被一條 行安全性策略所允許(不過,表的擁有者通常不服從行安全性策略)。如果表上不存在安全策略,如果沒有配置安全策略,所有的資料查詢和更新都會禁止,但是對全表進行操作的命令,比如 TRUNCATE 和 REFERENCES 不受影響。
行安全性策略可以針對特定的命令、角色或者兩者。一條策略可以被指定為適用於ALL命令,或者查詢(SELECT)、 插入(INSERT)、更新(UPDATE)或者刪除(DELETE)。同一個策略可分配多個角色,並且通常的角色成員關係和繼承規則也適用。但是表的所有者,超級使用者 (postgres) 以及加上了 BYPASSRLS 屬性的角色不受安全性的限制。
只有所有者才具有啟用 / 禁用行級安全性,給表新增策略的許可權。
常見命令:
CREATE POLICY :建立策略
ALTER POLICY :修改策略
DROP POLICY :刪除策略
ALTER TABLE :用於行級安全性的啟用 / 禁用。
每個策略都有一個名字,每個表可以定義多個策略,因為策略是針對表的,所以表內的多個策略名字必須唯一,但是不同的表可以有同名的策略,當表有多個策略時,多個策略之間是 OR 的關係。
2、相關示例
新建一張表,並插入三條資料:
CREATE TABLE userlist (id text, name text);insert into userlist values(1,‘user01’);insert into userlist values(2,‘user02’);insert into userlist values(3,‘user03’);
執行查詢操作,檢視資料表中的結果
select * from userlist; id | name ——+———— 2 | user02 1 | user01 3 | user03(3 rows)
建立一個使用者,並授予其查詢許可權;
create user user01 with password ‘123456’;create user user02 with password ‘123456’;grant select ON public。userlist to user01,user02;grant insert ON public。userlist to user01,user02;grant update ON public。userlist to user01,user02;
此時user01、user02可以執行查詢操作,獲得整個表userlist的全部資料;
用例1:限制user01使用者限制只能查詢表userlist中name=‘user01’的資料
建立策略,
create policy user01_select ON userlist for select to user01 using(current_user=name);
此時查看錶結構;
\d userlist
返回結果如下:
Table “public。userlist” Column | Type | Collation | Nullable | Default ————+————+——————-+——————+————- id | text | | | name | text | | | Policies (row security disabled): POLICY “user01_select” FOR SELECT TO user01 USING (((CURRENT_USER)::text = name))
從這兒我們可以看到該策略是沒有啟用的,處於disabled狀態;
要開啟表的行級安全,需要使用ALTER TABLE命令:
alter table userlist enable row level security ;
使用賬號user01連線資料庫
\c - user01You are now connected to database “memfire” as user “user01”。
執行查詢操作,得到結果如下:
select * from userlist id | name ——+———— 1 | user01(1 row)
開啟行級許可權後,user01僅能夠查詢name=‘user01’的資料
使用賬號user02連線資料庫
\c - user02You are now connected to database “memfire” as user “user02”。
執行查詢操作,得到結果如下:
select * from userlist; id | name ——+————(0 rows)
開啟行級許可權後,user02無法查詢資料,說明策略生效了
用例2:建立新增資料策略
切換到資料表owner賬戶, 建立一個插入策略;
create policy user01_insert on userlist for insert to user01 with check(true);
執行命令,檢視已經建立的策略;
——pg_policies可以檢視已經建立的策略select * from pg_policies;
返回結果如下:
schemaname | tablename | policyname | permissive | roles | cmd | qual | with_check ——————+——————-+————————-+——————+——————+————+————————————————-+—————— public | userlist | user01_select | PERMISSIVE | {user01} | SELECT | ((CURRENT_USER)::text = name) | public | userlist | user01_insert | PERMISSIVE | {user01} | INSERT | | true(2 rows)
使用賬號user01連線資料庫
\c - user01You are now connected to database “memfire” as user “user01”。
插入一條新資料
insert into userlist values(4,‘user01’);INSERT 0 1
執行查詢操作
select * from userlist; id | name ——+———— 4 | user01 1 | user01(2 rows)
使用賬號user02連線資料庫
\c - user02You are now connected to database “memfire” as user “user02”。
插入一條新資料
insert into userlist values(5,‘user02’);ERROR: new row violates row-level security policy for table “userlist”
採用user02無法插入資料,說明建立的策略生效。
用例3:建立刪除資料策略
切換到資料表owner賬戶, 建立一個插入策略;
create policy user01_delete on userlist for delete to user01 using(current_user=name);
執行命令,檢視已經建立的策略;
——pg_policies可以檢視已經建立的策略select * from pg_policies;
返回結果如下:
schemaname | tablename | policyname | permissive | roles | cmd | qual | with_check ——————+——————-+————————-+——————+——————+————+————————————————-+—————— public | userlist | user01_select | PERMISSIVE | {user01} | SELECT | ((CURRENT_USER)::text = name) | public | userlist | user01_insert | PERMISSIVE | {user01} | INSERT | | true public | userlist | user01_delete | PERMISSIVE | {user01} | DELETE | ((CURRENT_USER)::text = name) | (3 rows)
執行查詢操作
select * from userlist;id | name ——+———— 2 | user02 4 | user01 1 | user01 3 | user03(4 rows)
使用賬號user01連線資料庫
\c - user01You are now connected to database “memfire” as user “user01”。
刪除資料
delete from userlist;DELETE 2
建立刪除策略後,user01僅能夠刪除name=‘user01’的資料
使用賬號user02連線資料庫
\c - user02You are now connected to database “memfire” as user “user02”。
執行刪除操作
memfire=> delete from userlist;DELETE 0
採用user02無法刪除資料,說明建立的策略生效。
樣例4. 限制user01使用者限制只能更新表userlist中name=‘user01’的資料
切換到資料表owner賬戶, 建立一個更新策略;
create policy user01_update on userlist for update to user01 using(current_user=name);
執行命令,檢視已經建立的策略;
——pg_policies可以檢視已經建立的策略select * from pg_policies;
返回結果如下:
schemaname | tablename | policyname | permissive | roles | cmd | qual | with_check ——————+——————-+————————-+——————+——————+————+————————————————-+—————— public | userlist | user01_select | PERMISSIVE | {user01} | SELECT | ((CURRENT_USER)::text = name) | public | userlist | user01_insert | PERMISSIVE | {user01} | INSERT | | true public | userlist | user01_delete | PERMISSIVE | {user01} | DELETE | ((CURRENT_USER)::text = name) | public | userlist | user01_update | PERMISSIVE | {user01} | UPDATE | ((CURRENT_USER)::text = name) | (4 rows)
插入三條資料:
insert into userlist values(1,‘user01’);insert into userlist values(4,‘user01’);insert into userlist values(2,‘user05’);
執行查詢操作:
select * from userlist; id | name ——+———— 2 | user02 5 | user02 4 | user01 1 | user01 3 | user03
更新所有name=“user01“的資料的id更新為2
update userlist set id=2;UPDATE 2
建立刪除策略後,user01僅能夠更新name=‘user01’的資料;
更新後,切換到表userlist表owner,執行查詢操作
select * from userlist; id | name ——+———— 2 | user02 5 | user02 2 | user01 2 | user01 3 | user03
今天就介紹到這兒,更多詳細內容,可以參考行安全性策略。
參考資料
建立策略:http://postgres。cn/docs/9。5/sql-createpolicy。html
修改策略:http://postgres。cn/docs/9。5/sql-alterpolicy。html
刪除策略:http://postgres。cn/docs/9。5/sql-droppolicy。html
用於行級安全性的啟用 / 禁用:http://postgres。cn/docs/9。5/sql-altertable。html
行安全性策略:http://postgres。cn/docs/9。5/ddl-rowsecurity。html