PostgreSQL是通過角色來管理數據庫訪問權限的,我們可以將一個角色看成是一個數據庫用戶,或者一組數據庫用戶。角色可以擁有數據庫對象,如表、索引,也可以把這些對象上的權限賦予其它角色,以控制哪些用戶對哪些對象擁有哪些權限。
一、數據庫角色:
1. 創建角色:
復制代碼 代碼如下:
CREATE ROLE role_name;
2. 刪除角色:
復制代碼 代碼如下:
DROP ROLE role_name;
3. 查詢角色:
檢查系統表pg_role,如:
復制代碼 代碼如下:
SELECT usename FROM pg_role;
也可以在psql中執行\du命令列出所有角色。
二、角色屬性:
一個數據庫角色可以有一系列屬性,這些屬性定義他的權限,以及與客戶認證系統的交互。
1. 登錄權限:
只有具有LOGIN屬性的角色才可以用於數據庫連接,因此我們可以將具有該屬性的角色視為登錄用戶,創建方法有如下兩種:
復制代碼 代碼如下:
CREATE ROLE name LOGIN PASSWORD '123456‘;
CREATE USER name PASSWORD '123456';
2. 超級用戶:
數據庫的超級用戶擁有該數據庫的所有權限,為了安全起見,我們最好使用非超級用戶完成我們的正常工作。和創建普通用戶不同,創建超級用戶必須是以超級用戶的身份執行以下命令:
復制代碼 代碼如下:
CREATE ROLE name SUPERUSER;
3. 創建數據庫:
角色要想創建數據庫,必須明確賦予創建數據庫的屬性,見如下命令:
復制代碼 代碼如下:
CREATE ROLE name CREATEDB;
4. 創建角色:
一個角色要想創建更多角色,必須明確給予創建角色的屬性,見如下命令:
復制代碼 代碼如下:
CREATE ROLE name CREATEROLE;
三、權限:
數據庫對象在被創建時都會被賦予一個所有者,通常而言,所有者就是執行對象創建語句的角色。對於大多數類型的對象,其初始狀態是只有所有者(或超級用戶)可以對該對象做任何事情。如果要允許其它用戶可以使用該對象,必須賦予適當的權限。PostgreSQL中預定義了許多不同類型的內置權限,如:SELECT、INSERT、UPDATE、DELETE、RULE、REFERENCES、TRIGGER、CREATE、TEMPORARY、EXECUTE和USAGE。
我們可以使用GRANT命令來賦予權限,如:
復制代碼 代碼如下:
GRANT UPDATE ON accounts TO joe;
對於上面的命令,其含義為將accounts表的update權限賦予joe角色。此外,我們也可以用特殊的名字PUBLIC把對象的權限賦予系統中的所有角色。在權限聲明的位置上寫ALL,表示把適用於該對象的所有權限都賦予目標角色。
要撤銷權限,使用合適的REVOKE命令:
復制代碼 代碼如下:
REVOKE ALL ON accounts FROM PUBLIC;
其含義為:對所有角色(PUBLIC)撤銷在accounts對象上的所有權限(ALL)。
四、角色成員:
在系統的用戶管理中,通常會把多個用戶賦予一個組,這樣在設置權限時只需給該組設置即可,撤銷權限時也是從該組撤消。在PostgreSQL中,首先需要創建一個代表組的角色,之後再將該角色的membership權限賦給獨立的用戶角色即可。
1. 創建一個組角色,通常而言,該角色不應該具有LOGIN屬性,如:
復制代碼 代碼如下:
CREATE ROLE name;
2. 使用GRANT和REVOKE命令添加和撤消權限:
復制代碼 代碼如下:
GRANT group_role TO role1, ... ;
REVOKE group_role FROM role1, ... ;
一個角色成員可以通過兩種方法使用組角色的權限,如:
1. 每個組成員都可以用SET ROLE命令將自己臨時"變成"該組成員,此後再創建的任何對象的所有者將屬於該組,而不是原有的登錄用戶。
2. 擁有INHERIT屬性的角色成員自動繼承它們所屬角色的權限。
見如下示例:
復制代碼 代碼如下:
CREATE ROLE joe LOGIN INHERIT; --INHERIT是缺省屬性。
CREATE ROLE admin NOINHERIT;
CREATE ROLE wheel NOINHERIT;
GRANT admin TO joe;
GRANT wheel TO admin;
現在我們以角色joe的身份與數據庫建立連接,那麼該數據庫會話將同時擁有角色joe和角色admin的權限,這是因為joe"繼承(INHERIT)"了admin的權限。然而與此不同的是,賦予wheel角色的權限在該會話中將不可用,因為joe角色只是wheel角色的一個間接成員,它是通過admin角色間接傳遞過來的,而admin角色卻含有NOINHERIT屬性,這樣wheel角色的權限將無法被joe繼承。
這樣wheel角色的權限將無法被joe繼承。此時,我們可以在該會話中執行下面的命令:
復制代碼 代碼如下:
SET ROLE admin;
在執行之後,該會話將只擁有admin角色的權限,而不再包括賦予joe角色的權限。同樣,在執行下面的命令之後,該會話只能使用賦予wheel的權限。
復制代碼 代碼如下:
SET ROLE wheel;
在執行一段時間之後,如果仍然希望將該會話恢復為原有權限,可以使用下列恢復方式之一:
復制代碼 代碼如下:
SET ROLE joe;
SET ROLE NONE;
RESET ROLE;
注意: SET ROLE命令總是允許選取當前登錄角色的直接或間接組角色。因此,在變為wheel之前沒必要先變成admin。
角色屬性LOGIN、SUPERUSER和CREATEROLE被視為特殊權限,它們不會像其它數據庫對象的普通權限那樣被繼承。如果需要,必須在調用SET ROLE時顯示指定擁有該屬性的角色。比如,我們也可以給admin角色賦予CREATEDB和CREATEROLE權限,然後再以joe的角色連接數據庫,此時該會話不會立即擁有這些特殊權限,只有當執行SET ROLE admin命令之後當前會話才具有這些權限。
要刪除一個組角色,執行DROP ROLE group_role命令即可。然而在刪除該組角色之後,它與其成員角色之間的關系將被立即撤銷(成員角色本身不會受影響)。不過需要注意的是,在刪除之前,任何屬於該組角色的對象都必須先被刪除或者將對象的所有者賦予其它角色,與此同時,任何賦予該組角色的權限也都必須被撤消。