Postgresql數(shù)據(jù)庫支持靈活的權(quán)限管理,可以控制一個角色(組、用戶)對某張表的讀、寫、更新、刪除等操作權(quán)限、執(zhí)行某個函數(shù)的權(quán)限以及操作(使用、更新等)視圖、序列的權(quán)限。
PG的權(quán)限管理功能比較強(qiáng)大,可以細(xì)化到對一張表的各個字段,比如禁止用戶訪問一張表里的密碼字段等,在稍后的內(nèi)容中給出詳細(xì)的解釋。
雖然在PG數(shù)據(jù)庫中把用戶、角色統(tǒng)一叫做角色,甚至創(chuàng)建語句都為create role XXX,但用戶和角色之間仍有一定的區(qū)別。在這里我們統(tǒng)一把擁有登錄權(quán)限的叫做用戶,沒有登錄權(quán)限的叫做角色,用此方式加以區(qū)分。
實際上,在PgAdmin管理工具中,可以看到用戶和角色的區(qū)別,沒有登錄權(quán)限的被放在組角色下,有登錄權(quán)限的被放在登錄角色下。
基本權(quán)限
用戶和角色都可以被賦予基本權(quán)限,比如創(chuàng)建數(shù)據(jù)庫權(quán)限、超級用戶權(quán)限、創(chuàng)建角色權(quán)限等。
比如創(chuàng)建用戶的語句為:
CREATE ROLE guest LOGIN
NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION;
注意上述Role guest擁有LOGIN的權(quán)限,所以叫它用戶。
創(chuàng)建角色的語句為:
CREATE ROLE "group"
NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION;
注意這里沒有LOGIN權(quán)限,所以是角色。
上述角色和用戶的創(chuàng)建語句中,都沒有賦予超級用戶、創(chuàng)建數(shù)據(jù)庫等權(quán)限。
操作數(shù)據(jù)庫對象權(quán)限
只能把數(shù)據(jù)庫對象的操作權(quán)限賦予沒有登錄權(quán)限的角色,而不能直接賦予擁有登錄權(quán)限的用戶。
那么這樣就帶來一個問題,怎么樣控制登錄用戶操作數(shù)據(jù)庫對象的權(quán)限呢?
答案是讓用戶成為角色的成員,此時用戶即可擁有角色的權(quán)限,進(jìn)一步限制了登錄用戶操作數(shù)據(jù)庫對象的權(quán)限。
如把上述角色group賦予guest用戶:
之后,guest用戶就擁有了group角色所擁有的數(shù)據(jù)庫對象權(quán)限。
比如控制group角色只能對class表執(zhí)行Insert操作:
GRANT INSERT ON TABLE class TO "group";
此時使用guest用戶登錄數(shù)據(jù)后,就只能對表class執(zhí)行insert操作,無法執(zhí)行delete、update等操作。
示例代碼如下,使用guest用戶登錄,訪問TEST數(shù)據(jù)庫下的class表。
Server [localhost]:
Database [postgres]:
Port [5433]:
Username [postgres]: guest
用戶 guest 的口令:
psql (9.4.5)
輸入 "help" 來獲取幫助信息.
postgres=> \c TEST
您現(xiàn)在已經(jīng)連線到數(shù)據(jù)庫 "TEST",用戶 "guest".
TEST=> select * from class;
ERROR: permission denied for relation class
TEST=> insert into class values(2,'class1');
INSERT 0 1
從上述結(jié)果中可以看到,guest用戶沒有權(quán)限查詢class表,但是可以插入數(shù)據(jù)庫。原因就是只對group角色賦予了class表的insert權(quán)限,然后guest用戶也就只有class表的insert權(quán)限。
前面說到PG的權(quán)限管理可以細(xì)化到表的某個字段,現(xiàn)在繼續(xù)用class表和guest用戶做實驗。
TEST=> \c postgres postgres;
您現(xiàn)在已經(jīng)連線到數(shù)據(jù)庫 "postgres",用戶 "postgres".
postgres=# \c TEST;
您現(xiàn)在已經(jīng)連線到數(shù)據(jù)庫 "TEST",用戶 "postgres".
TEST=# grant select(num) on class to "group";
GRANT
TEST=# \echo 切換到postgres用戶連接TEST數(shù)據(jù)庫,對class表的num字段的select權(quán)限賦予group角色
切換到postgres用戶連接TEST數(shù)據(jù)庫,對class表的num字段的select權(quán)限賦予group角色
TEST=# \c TEST guest
用戶 guest 的口令:
您現(xiàn)在已經(jīng)連線到數(shù)據(jù)庫 "TEST",用戶 "guest".
TEST=> \echo 切換回guest用戶登錄TEST數(shù)據(jù)庫
切換回guest用戶登錄TEST數(shù)據(jù)庫
TEST=> select * from class;
ERROR: permission denied for relation class
TEST=> select num from class;
num
-----
1
2
(2 行記錄)
從上述結(jié)果中可以看到,guest用戶依然沒有查詢class表的權(quán)限,但是卻有了查詢class表里的num字段的權(quán)限。
在PG數(shù)據(jù)庫中不單單可以控制操作表的權(quán)限,其他數(shù)據(jù)庫對象,比如序列、函數(shù)、視圖等都可以控制。
所以PG的權(quán)限控制功能非常強(qiáng)大。
補(bǔ)充:Postgres用戶對數(shù)據(jù)庫的權(quán)限
用戶對數(shù)據(jù)庫的權(quán)限(登錄、超級用戶權(quán)限)
(1)查看當(dāng)前數(shù)據(jù)庫中有用戶highgo和用戶a
highgo=#\du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------+-----------
a | | {}
highgo | Superuser, Create role, Create DB, Replication | {}
(2)查看確認(rèn)當(dāng)前連接的用戶為超級用戶highgo,且該用戶后創(chuàng)建角色和數(shù)據(jù)庫的權(quán)限等
highgo=#select current_user;
current_user
--------------
highgo
(1row)
(3)查看當(dāng)前集群中的數(shù)據(jù)庫
highgo=#\l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+--------+----------+------------+------------+-------------------
highgo | highgo | UTF8 | zh_CN.utf8 |zh_CN.utf8 |
template0 | highgo | UTF8 | zh_CN.utf8 | zh_CN.utf8 | =c/highgo +
| | | | | highgo=CTc/highgo
template1 | highgo | UTF8 | zh_CN.utf8 | zh_CN.utf8 | =c/highgo +
| | | | | highgo=CTc/highgo
(3rows)
(4)使用普通用戶a連接數(shù)據(jù)庫正常
highgo=#\c highgo a
Youare now connected to database "highgo" as user "a".
highgo=>select current_user;
current_user
--------------
a
(1row)
(5)使用超級用戶highgo連接數(shù)據(jù)庫正常
highgo=>\c highgo highgo
Youare now connected to database "highgo" as user "highgo".
highgo=#select current_user;
current_user
--------------
highgo
(1row)
(6)在超級用戶連接highgo后,設(shè)置不允許普通用戶a連接數(shù)據(jù)庫
highgo=#alter role a nologin;
ALTER ROLE
highgo=#\c highgo a
致命錯誤: 不允許角色"a" 進(jìn)行登錄
Previousconnection kept
highgo=#
(7)在超級用戶連接highgo后,設(shè)置不允許普通用戶a連接數(shù)據(jù)庫后,賦予用戶a超級用戶權(quán)限后仍然無法連接數(shù)據(jù)庫
highgo=#alter role a superuser;
ALTERROLE
highgo=#\du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------+-----------
a | Superuser, Cannot login | {}
highgo | Superuser, Create role, Create DB, Replication | {}
highgo=#\c highgo a
致命錯誤: 不允許角色"a" 進(jìn)行登錄
Previousconnection kept
(8)將登錄數(shù)據(jù)庫的權(quán)限賦予用戶a后,用戶a可登錄數(shù)據(jù)庫
highgo=#alter role a login;
ALTERROLE
highgo=#\c highgo a
Youare now connected to database "highgo" as user "a".
highgo=#select current_user;
current_user
--------------
a
(1row)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。
您可能感興趣的文章:- 基于PostgreSQL 權(quán)限解讀
- PostgreSQL 默認(rèn)權(quán)限查看方式
- Postgresql 賦予用戶權(quán)限和撤銷權(quán)限的實例
- 查看postgresql數(shù)據(jù)庫用戶系統(tǒng)權(quán)限、對象權(quán)限的方法
- PostgreSQL教程(十二):角色和權(quán)限管理介紹
- 用一整天的時間安裝postgreSQL NTFS權(quán)限