原博地址 https://yq.aliyun.com/articles/41512?spm=a2c4e.11153940.0.0.20b7640fcDiFQA
關於PostgreSQL的邏輯架構和權限體系,可以參考
https://yq.aliyun.com/articles/41210
本文將給大家介紹一下如何批量管理表,視圖,物化視圖的權限。
以及如何管理默認權限,批量賦予schema的權限。
對整個SCHEMA的對象進行權限管理
PostgreSQL 從9.0開始就提供了比較方便的對整個schema的指定對象賦權給目標用的語法。
http://www.postgresql.org/docs/9.5/static/sql-grant.html
例子
GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER } [, ...] | ALL [ PRIVILEGES ] } ON { [ TABLE ] table_name [, ...] | ALL TABLES IN SCHEMA schema_name [, ...] } TO role_specification [, ...] [ WITH GRANT OPTION ]REVOKE [ GRANT OPTION FOR ] { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER } [, ...] | ALL [ PRIVILEGES ] } ON { [ TABLE ] table_name [, ...] | ALL TABLES IN SCHEMA schema_name [, ...] } FROM { [ GROUP ] role_name | PUBLIC } [, ...] [ CASCADE | RESTRICT ]
將schema digoal下的所有表的select,update權限賦予給test用戶。
注意
如果digoal.*中包含了非當前用戶的表,並且當前用戶非超級用戶,並且當前用戶沒有這些表的select,update的with grant option權限。將報錯。
換句話說,如果要確保這個賦權操作萬無一失,可以選擇使用超級用戶來執行。
grant select,update on all tables in schema digoal to test;
將schema digoal下的所有表的select,update權限從test用戶回收。
revoke select,update on all tables in schema digoal from test;
在對整個schema下的所有對象的權限管理完后, 別忘記了在對象之上,還需要對schema、database、instance進行相應的賦權。
如何設置用戶創建的對象的默認權限
另一個問題,如何設置用戶新建的對象的默認權限?
在PostgreSQL 9.0以后新加的語法:
http://www.postgresql.org/docs/9.5/static/sql-alterdefaultprivileges.html
例如
ALTER DEFAULT PRIVILEGES [ FOR { ROLE | USER } target_role [, ...] ] [ IN SCHEMA schema_name [, ...] ] abbreviated_grant_or_revokewhere abbreviated_grant_or_revoke is one of:GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER } [, ...] | ALL [ PRIVILEGES ] } ON TABLES TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ]
例子:
將digoal用戶未來在public下面創建的表的select,update權限默認賦予給test用戶.
postgres=> alter default privileges for role digoal in schema public grant select,update on tables to test; ALTER DEFAULT PRIVILEGES
將test用戶未來在public,digoal下面創建的表的select,update權限默認賦予給digoal用戶.
postgres=# alter default privileges for role test in schema public,digoal grant select,update on tables to digoal; ALTER DEFAULT PRIVILEGES
查看已經賦予的默認權限
postgres=> \ddp+ Default access privileges Owner | Schema | Type | Access privileges ----------+--------+-------+--------------------------- digoal | public | table | test=rw/digoal test | digoal | table | digoal=rw/test test | public | table | digoal=rw/test
或
SELECT pg_catalog.pg_get_userbyid(d.defaclrole) AS "Owner", n.nspname AS "Schema", CASE d.defaclobjtype WHEN 'r' THEN 'table' WHEN 'S' THEN 'sequence' WHEN 'f' THEN 'function' WHEN 'T' THEN 'type' END AS "Type", pg_catalog.array_to_string(d.defaclacl, E'\n') AS "Access privileges"FROM pg_catalog.pg_default_acl d LEFT JOIN pg_catalog.pg_namespace n ON n.oid = d.defaclnamespaceORDER BY 1, 2, 3; Owner | Schema | Type | Access privileges ----------+--------+-------+--------------------------- digoal | public | table | test=rw/digoal postgres | | table | postgres=arwdDxt/postgres+ | | | digoal=arwdDxt/postgres test | digoal | table | digoal=rw/test test | public | table | digoal=rw/test (4 rows)
如何定制批量管理權限
將"指定用戶" owne 的表、視圖、物化視圖的"指定權限"賦予給"指定用戶",並排除"指定對象"
這個需求需要寫一個函數來完成,如下
create or replace function g_or_v ( g_or_v text, -- 輸入 grant or revoke 表示賦予或回收 own name, -- 指定用戶 owner target name, -- 賦予給哪個目標用戶 grant privilege to who? objtyp text, -- 對象類別: 表, 物化視圖, 視圖 object type 'r', 'v' or 'm', means table,view,materialized view exp text[], -- 排除哪些對象, 用數組表示, excluded objects priv text -- 權限列表, privileges, ,splits, like 'select,insert,update') returns void as $$ declare nsp name; rel name; sql text; tmp_nsp name := '';begin for nsp,rel in select t2.nspname,t1.relname from pg_class t1,pg_namespace t2 where t1.relkind=objtyp and t1.relnamespace=t2.oid and t1.relowner=(select oid from pg_roles where rolname=own) loop if (tmp_nsp = '' or tmp_nsp <> nsp) and lower(g_or_v)='grant' then -- auto grant schema to target user sql := 'GRANT usage on schema "'||nsp||'" to '||target; execute sql; raise notice '%', sql; end if; tmp_nsp := nsp; if (exp is not null and nsp||'.'||rel = any (exp)) then raise notice '% excluded % .', g_or_v, nsp||'.'||rel; else if lower(g_or_v) = 'grant' then sql := g_or_v||' '||priv||' on "'||nsp||'"."'||rel||'" to '||target ; elsif lower(g_or_v) = 'revoke' then sql := g_or_v||' '||priv||' on "'||nsp||'"."'||rel||'" from '||target ; else raise notice 'you must enter grant or revoke'; end if; raise notice '%', sql; execute sql; end if; end loop;end; $$ language plpgsql;
例子
將digoal用戶的所有表(除了'public.test'和'public.abc')的select, update權限賦予給test用戶.
postgres=# select g_or_v('grant', 'digoal', 'test', 'r', array['public.test', 'public.abc'], 'select, update');NOTICE: GRANT usage on schema "public" to testNOTICE: grant select, update on "public"."tb1l" to testNOTICE: grant select, update on "public"."new" to test g_or_v -------- (1 row) postgres=# \dp+ public.tb1l Access privileges Schema | Name | Type | Access privileges | Column privileges | Policies --------+------+-------+-------------------+-------------------+---------- public | tb1l | table | test=rw/digoal | | (1 row) postgres=# \dp+ public.new Access privileges Schema | Name | Type | Access privileges | Column privileges | Policies --------+------+-------+-----------------------+-------------------+---------- | | | test=rw/digoal | | (1 row)
從 test 用戶回收digoal用戶的所有表(除了'public.test'和'public.abc')的update權限.
postgres=# select g_or_v('revoke', 'digoal', 'test', 'r', array['public.test', 'public.abc'], 'update');NOTICE: revoke update on "public"."tb1l" from testNOTICE: revoke update on "public"."new" from test g_or_v -------- (1 row) postgres=# \dp+ public.tb1l Access privileges Schema | Name | Type | Access privileges | Column privileges | Policies --------+------+-------+-------------------+-------------------+---------- public | tb1l | table | test=r/digoal | | (1 row) postgres=# \dp+ public.new Access privileges Schema | Name | Type | Access privileges | Column privileges | Policies --------+------+-------+-----------------------+-------------------+---------- | | | test=r/digoal | | (1 row)