postgre 之 行安全性策略
(一)介紹
使用 ALTER TABLE ... ENABLE ROW LEVEL SECURITY 在一個表上啟用行安全性 。表擁有者通常也能繞過行安全性,不過表擁有者 可以選擇用ALTER TABLE ... FORCE ROW LEVEL SECURITY來服從行安全性。
具有BYPASSRLS
屬性的超級用戶和角色在訪問一個表時總是 可以繞過行安全性系統。
一旦啟用,所有對該表行進行選擇或者修改的普通操作都必須被一條行安全性策略所允許。
如果 表上不存在策略,將使用一條默認的否定策略,即所有的行都不可見或者不能 被修改。
但是應用在整個表上的操作不服從行安全性,例如TRUNCATE
和 REFERENCES
行安全性策略可以針對特定的命令、角色或者兩者。一條策略可以被指定為 適用於ALL
命令,或者SELECT
、 INSERT
、UPDATE
或者DELETE
。 可以為一條給定策略分配多個角色,並且通常的角色成員關系和繼承規則也適用。
對於每一行,在計算任何來自用戶查詢的條件或函數之前,先會計算這個策略是否通過。
當多條策略適用於一個給定查詢時,會用OR
(用於寬松的策略,這是默認的)或AND
(用於限制性策略) 將它們組合起來。多個限制性策略必須都通過,然後至少有一個寬松策略,還得通過。
(二)語法詳解
CREATE POLICY name ON table_name [ AS { PERMISSIVE | RESTRICTIVE } ] -- 寬松的 或 嚴格的。默認是 寬容的 [ FOR { ALL | SELECT | INSERT | UPDATE | DELETE } ] -- 允許哪些權限,默認是ALL,所有權限。未被指定的權限直接否定 [ TO { role_name | PUBLIC | CURRENT_USER | SESSION_USER } [, ...] ] -- 角色,默認是PUBLIC [ USING ( using_expression ) ] -- 已經存在的行的檢查條件,(with check不存在,使用using檢查更新後的行)。insert策略不能有這個 [ WITH CHECK ( check_expression ) ] -- 新增行的檢查條件,這理不止insert,由於mvcc,update也新增行。select策略和delete策略不能有這個
如果沒有定義WITH CHECK表達式,那麽 USING表達式將被用於決定哪些行可見(普通 USING情況)以及允許哪些行被增加( WITH CHECK情況)。
update操作需要select和update策略
delete操作需要select和delete策略
(三)例子
作為一個簡單的例子,這裏是如何在account
關系上 創建一條策略以允許只有managers
角色的成員能訪問行, 並且只能訪問它們賬戶的行:
CREATE TABLE accounts (manager text, company text, contact_email text); ALTER TABLE accounts ENABLE ROW LEVEL SECURITY; CREATE POLICY account_managers ON accounts TO managers USING (manager = current_user);
如果沒有指定角色或者使用了特殊的用戶名PUBLIC
, 則該策略適用於系統上所有的用戶。要允許所有用戶訪問users
表中屬於他們自己的行,可以使用一條簡單的策略:
CREATE POLICY user_policy ON users USING (user_name = current_user);
要對相對於可見行是被增加到表中的行使用一條不同的策略,可以使用 WITH CHECK
子句。這條策略將允許所有用戶查看 users
表中的所有行,但是只能修改它們自己的行(實際可以刪除其他user的行):
CREATE POLICY user_policy ON users USING (true) WITH CHECK (user_name = current_user);
postgre 之 行安全性策略