[轉]PostgreSQL 邏輯結構 和 權限體系 介紹


摘要: 本文旨在幫助用戶理解PostgreSQL的邏輯結構和權限體系,幫助用戶快速的理解和管理數據庫的權限。 邏輯結構 最上層是實例,實例中允許創建多個數據庫,每個數據庫中可以創建多個schema,每個schema下面可以創建多個對象。對象包括表、物化視圖、操作符、索引、視圖、序列、函數、... 等

本文旨在幫助用戶理解PostgreSQL的邏輯結構和權限體系,幫助用戶快速的理解和管理數據庫的權限。

邏輯結構

最上層是實例,實例中允許創建多個數據庫,每個數據庫中可以創建多個schema,每個schema下面可以創建多個對象。
對象包括表、物化視圖、操作符、索引、視圖、序列、函數、... 等等。
1
在數據庫中所有的權限都和角色(用戶)掛鈎,public是一個特殊角色,代表所有人。
超級用戶是有允許任意操作對象的,普通用戶只能操作自己創建的對象。
另外有一些對象是有賦予給public角色默認權限的,所以建好之后,所以人都有這些默認權限。

權限體系

2
實例級別的權限由pg_hba.conf來控制,例如 :

# TYPE DATABASE USER ADDRESS METHOD # "local" is for Unix domain socket connections only local all all trust # IPv4 local connections: host all all 127.0.0.1/32 trust host all postgres 0.0.0.0/0 reject host all all 0.0.0.0/0 md5 

以上配置的解釋
允許任何本地用戶無密碼連接任何數據庫
不允許postgres用戶從任何外部地址連接任何數據庫
允許其他任何用戶從外部地址通過密碼連接任何數據庫

數據庫級別的權限,包括允許連接數據庫,允許在數據庫中創建schema。
默認情況下,數據庫在創建后,允許public角色連接,即允許任何人連接。
默認情況下,數據庫在創建后,不允許除了超級用戶和owner之外的任何人在數據庫中創建schema。
默認情況下,數據庫在創建后,會自動創建名為public 的schema,這個schema的all權限已經賦予給public角色,即允許任何人在里面創建對象。

schema級別的權限,包括允許查看schema中的對象,允許在schema中創建對象。
默認情況下新建的schema的權限不會賦予給public角色,因此除了超級用戶和owner,任何人都沒有權限查看schema中的對象或者在schema中新建對象。

schema使用 , 特別注意

According to the SQL standard, the owner of a schema always owns all objects within it. PostgreSQL allows schemas to contain objects owned by users other than the schema owner. This can happen only if the schema owner grants the CREATE privilege on his schema to someone else, or a superuser chooses to create objects in it. schema的owner默認是該schema下的所有對象的owner,但是PostgreSQL又允許用戶在別人的schema下創建對象,所以一個對象可能屬於兩個owner,而且schema 的owner有 drop對象的權限。 對於兩個owner都有drop的權限,這個我個人認為是一個BUG。 所以千萬不要把自己的對象創建到別人的schema下面,那很危險。 

對象級別的權限,每種類型的對象權限屬性都不一樣,具體請參考
http://www.postgresql.org/docs/9.5/static/sql-grant.html
以表為例,可以有SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER這些權限。

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 ] GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( column_name [, ...] ) [, ...] | ALL [ PRIVILEGES ] ( column_name [, ...] ) } ON [ TABLE ] table_name [, ...] TO role_specification [, ...] [ WITH GRANT OPTION ] GRANT { { USAGE | SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] } ON { SEQUENCE sequence_name [, ...] | ALL SEQUENCES IN SCHEMA schema_name [, ...] } TO role_specification [, ...] [ WITH GRANT OPTION ] GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] } ON DATABASE database_name [, ...] TO role_specification [, ...] [ WITH GRANT OPTION ] GRANT { USAGE | ALL [ PRIVILEGES ] } ON DOMAIN domain_name [, ...] TO role_specification [, ...] [ WITH GRANT OPTION ] GRANT { USAGE | ALL [ PRIVILEGES ] } ON FOREIGN DATA WRAPPER fdw_name [, ...] TO role_specification [, ...] [ WITH GRANT OPTION ] GRANT { USAGE | ALL [ PRIVILEGES ] } ON FOREIGN SERVER server_name [, ...] TO role_specification [, ...] [ WITH GRANT OPTION ] GRANT { EXECUTE | ALL [ PRIVILEGES ] } ON { FUNCTION function_name ( [ [ argmode ] [ arg_name ] arg_type [, ...] ] ) [, ...] | ALL FUNCTIONS IN SCHEMA schema_name [, ...] } TO role_specification [, ...] [ WITH GRANT OPTION ] GRANT { USAGE | ALL [ PRIVILEGES ] } ON LANGUAGE lang_name [, ...] TO role_specification [, ...] [ WITH GRANT OPTION ] GRANT { { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] } ON LARGE OBJECT loid [, ...] TO role_specification [, ...] [ WITH GRANT OPTION ] GRANT { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] } ON SCHEMA schema_name [, ...] TO role_specification [, ...] [ WITH GRANT OPTION ] GRANT { CREATE | ALL [ PRIVILEGES ] } ON TABLESPACE tablespace_name [, ...] TO role_specification [, ...] [ WITH GRANT OPTION ] GRANT { USAGE | ALL [ PRIVILEGES ] } ON TYPE type_name [, ...] TO role_specification [, ...] [ WITH GRANT OPTION ] where role_specification can be: [ GROUP ] role_name | PUBLIC | CURRENT_USER | SESSION_USER GRANT role_name [, ...] TO role_name [, ...] [ WITH ADMIN OPTION ] 

簡單介紹一下grant的一些通用選項
WITH ADMIN OPTION表示被賦予權限的用戶,拿到對應的權限后,還能將對應的權限賦予給其他人,否則只能自己有這個權限,但是不能再賦予給其他人。

用戶

用戶,角色在PostgreSQL是一個概念。

public

public角色,代表所有人的意思。

如何查看和解讀一個對象的當前權限狀態

以表為例 :

select relname,relacl from pg_class where relkind='r'; 

或者執行

SELECT n.nspname as "Schema", c.relname as "Name", CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'view' WHEN 'm' THEN 'materialized view' WHEN 'S' THEN 'sequence' WHEN 'f' THEN 'foreign table' END as "Type", pg_catalog.array_to_string(c.relacl, E'\n') AS "Access privileges", pg_catalog.array_to_string(ARRAY( SELECT attname || E':\n ' || pg_catalog.array_to_string(attacl, E'\n ') FROM pg_catalog.pg_attribute a WHERE attrelid = c.oid AND NOT attisdropped AND attacl IS NOT NULL ), E'\n') AS "Column privileges", pg_catalog.array_to_string(ARRAY( SELECT polname || CASE WHEN polcmd != '*' THEN E' (' || polcmd || E'):' ELSE E':' END || CASE WHEN polqual IS NOT NULL THEN E'\n (u): ' || pg_catalog.pg_get_expr(polqual, polrelid) ELSE E'' END || CASE WHEN polwithcheck IS NOT NULL THEN E'\n (c): ' || pg_catalog.pg_get_expr(polwithcheck, polrelid) ELSE E'' END || CASE WHEN polroles <> '{0}' THEN E'\n to: ' || pg_catalog.array_to_string( ARRAY( SELECT rolname FROM pg_catalog.pg_roles WHERE oid = ANY (polroles) ORDER BY 1 ), E', ') ELSE E'' END FROM pg_catalog.pg_policy pol WHERE polrelid = c.oid), E'\n') AS "Policies" FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('r', 'v', 'm', 'S', 'f') AND n.nspname !~ '^pg_' AND pg_catalog.pg_table_is_visible(c.oid) ORDER BY 1, 2; 

得到權限說明如下

 Schema | Name | Type | Access privileges | Column privileges | Policies --------+-----------------+----------+--------------------------------+-------------------+---------- public | sbtest1 | table | postgres=arwdDxt/postgres +| | | | | digoal=a*r*w*d*D*x*t*/postgres | | public | sbtest10 | table | postgres=arwdDxt/postgres | | public | sbtest10_id_seq | sequence | | | public | sbtest11 | table | postgres=arwdDxt/postgres | | public | sbtest11_id_seq | sequence | | | public | sbtest12 | table | postgres=arwdDxt/postgres | | public | sbtest12_id_seq | sequence | | |

解釋一下 Access privileges
rolename=xxx 其中rolename就是被賦予權限的用戶名,即權限被賦予給誰了?
=xxx 表示這個權限賦予給了public角色,即所有人
/yyyy 表示是誰賦予的這個權限?
權限的含義如下

rolename=xxxx -- privileges granted to a role =xxxx -- privileges granted to PUBLIC r -- SELECT ("read") w -- UPDATE ("write") a -- INSERT ("append") d -- DELETE D -- TRUNCATE x -- REFERENCES t -- TRIGGER X -- EXECUTE U -- USAGE C -- CREATE c -- CONNECT T -- TEMPORARY arwdDxt -- ALL PRIVILEGES (for tables, varies for other objects) * -- grant option for preceding privilege /yyyy -- role that granted this privilege 

例子
賦予權限的人是postgres用戶, sbtest2表的select權限被賦予給了digoal用戶。

postgres=# grant select on sbtest2 to digoal; GRANT postgres=# \dp+ sbtest2 Access privileges Schema | Name | Type | Access privileges | Column privileges | Policies --------+---------+-------+---------------------------+-------------------+---------- public | sbtest2 | table | postgres=arwdDxt/postgres+| | | | | digoal=r/postgres | | (1 row) 

回收權限一定要針對已有的權限來,如果你發現這里的權限還在,那照着權限回收即可。
例如

revoke select on sbtest2 from digoal; 

參考

grant
revoke

更高基本的安全控制

PostgreSQL還支持凌駕於基本權限體系之上的安全策略,這些安全策略一般在企業級的商業數據庫中才有。

行安全策略

https://yq.aliyun.com/articles/4271

(原文地址:https://yq.aliyun.com/articles/41210)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM