PostgreSQL角色數據庫
PostgreSQL經過「角色」來對數據庫進行管理,我對它「角色」定義理解是:角色(role)=組(group)+用戶(user),或者是group/user=role,緣由以下:oracle
user=role:user徹底能夠理解爲有login權限的role函數
group=role:最能說明這一點的是create role命令中的role參數能夠將新定義的角色變爲group組spa
public是一個特殊的角色,雖然平日不能以public身份登錄數據庫,但它確實是存在的,它默認擁有:繼承
數據庫:connect,temp/temprary權限,與模式無關ip
public模式:usage,create權限,與數據庫無關it
函數:execute權限,僅限於public模式下io
language語言:usage權限,與模式無關table
更爲重要的是,public角色屬於一個全局性的角色,這就意味着你所建立的角色均可以理解爲是public角色組成員,並且對public權限的繼承徹底不受NOINHERIT的控制,一旦建立了一個擁有login權限的角色,它會當即繼承擁有上述權限,此時若是想經過revoke(好比revoke connect on database)來回收的話不會成功,由於這是經過組-組成員來繼承的,這種繼承權限沒法經過單純的對角色成員revoke掉,只能對組進行revoke,經過繼承來實現回收。coding
//實驗一:public角色不存在,但能影響新建角色
1.驗證public角色不存在
lihao=# create database db1 owner "lihao";
CREATE DATABASE
lihao=# \du+
List of roles
Role name | Attributes | Member of | Description
-----------+--------------------------------------------------------+--------------+-------------
lihao | Superuser, Create role, Create DB, Replication | {} |
lihao=# \c db1 public
FATAL: role "public" does not exist
Previous connection kept
2.驗證public角色的權限會默認繼承給新建用戶
lihao=# create role role1 login password '123456';
CREATE ROLE
lihao=# \du+
List of roles
Role name | Attributes | Member of | Description
-----------+------------------------------------------------+-----------+-------------
lihao | Superuser, Create role, Create DB, Replication | {} |
role1 | | {} |
lihao=# \l+
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges | Size | Tablespace | Description
-----------+-------+----------+-------------+-------------+-------------------+---------+------------+-------------
db1 | lihao | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | 6625 kB | pg_default |
lihao=# \c db1 role1
You are now connected to database "db1" as user "role1"
db1=> \dn+
List of schemas
Name | Owner | Access privileges | Description
---------+--------------+----------------------+------------------------
public | lihao | lihao=UC/lihao | standard public schema
| | =UC/lihao |
(1 row)
db1=> create temp table t1 (id int);
CREATE TABLE
db1=> create table t2 (id int);
CREATE TABLE
db1=> \d
List of relations
Schema | Name | Type | Owner
-----------+--------------------------+----------+-------
pg_temp_3 | t1 | table | role1?
public | t2 | table | role1
//在建立角色時沒有進行賦權,但它確實擁有這些權限,那麼經過revoke看是否能回收掉
db1=> \c db1 lihao
You are now connected to database "db1" as user "lihao".
db1=# revoke connect on database db1 from role1;
REVOKE
db1=# revoke create on schema public from role1;
REVOKE
db1=# \c db1 role1
You are now connected to database "db1" as user "role1".
db1=> create table t3 (id int);
CREATE TABLE
db1=> \d
List of relations
Schema | Name | Type | Owner
-----------+--------------------------+----------+-------
pg_temp_3 | t1 | table | role1
public | t2 | table | role1
public | t3 | table | role1
3.驗證NOINHERIT
db1=> \c db1 lihao
You are now connected to database "db1" as user "lihao".
db1=# create role role2 login noinherit password '123456';
CREATE ROLE
db1=# \c db1 role2
You are now connected to database "db1" as user "role2".
db1=> create table t4 (id int);
CREATE TABLE
db1=> \d
List of relations
Schema | Name | Type | Owner
-----------+--------------------------+----------+-------
pg_temp_3 | t1 | table | role1
public | t2 | table | role1
public | t3 | table | role1
public | t4 | table | role2
經過實驗一能夠看到,建立用戶時雖然沒有賦權,可是它默認擁有上面的權限,考慮是不是繼承的,經過revoke來驗證,但顯然revoke無效,雖然命令提示成功了(這裏一樣的revoke操做,oracle下會報錯用戶沒有被賦予該權限,沒法回收),並且另一個使用NOINHERIT建立的角色仍能使用這些權限。
此時解決辦法就是從public角色上revoke掉這些權限,執行命令revoke all on schema public from public;和revoke all on database DB_NAME from public;命令執行以前和以後所建立的角色均失去了執行命令所在庫以及庫中public模式的全部權限,但不會影響對其餘庫和它們的public模式的訪問。
//實驗二:驗證對public角色的revoke操做
1.驗證public角色不存在
lihao=# create database db1 owner "lihao";
CREATE DATABASE
lihao=# \du+
List of roles
Role name | Attributes | Member of | Description
-----------+--------------------------------------------------------+--------------+-------------
lihao | Superuser, Create role, Create DB, Replication | {} |
lihao=# \c db1 public
FATAL: role "public" does not exist
Previous connection kept
2.驗證public角色的權限會默認繼承給新建用戶
lihao=# create role role1 login password '123456';
CREATE ROLE
lihao=# \du+
List of roles
Role name | Attributes | Member of | Description
-----------+------------------------------------------------+-----------+-------------
lihao | Superuser, Create role, Create DB, Replication | {} |
role1 | | {} |
lihao=# \l+
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges | Size | Tablespace | Description
-----------+-------+----------+-------------+-------------+-------------------+---------+------------+-------------
db1 | lihao | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | 6625 kB | pg_default |
lihao=# \c db1 role1
You are now connected to database "db1" as user "role1"
db1=> \dn+
List of schemas
Name | Owner | Access privileges | Description
---------+--------------+----------------------+------------------------
public | lihao | lihao=UC/lihao | standard public schema
| | =UC/lihao |
(1 row)
db1=> create temp table t1 (id int);
CREATE TABLE
db1=> create table t2 (id int);
CREATE TABLE
db1=> \d
List of relations
Schema | Name | Type | Owner
-----------+--------------------------+----------+-------
pg_temp_3 | t1 | table | role1?
public | t2 | table | role1
//在建立角色時沒有進行賦權,但它確實擁有這些權限,那麼經過revoke看是否能回收掉
db1=> \c db1 lihao
You are now connected to database "db1" as user "lihao".
db1=# revoke connect on database db1 from role1;
REVOKE
db1=# revoke create on schema public from role1;
REVOKE
db1=# \c db1 role1
You are now connected to database "db1" as user "role1".
db1=> create table t3 (id int);
CREATE TABLE
db1=> \d
List of relations
Schema | Name | Type | Owner
-----------+--------------------------+----------+-------
pg_temp_3 | t1 | table | role1
public | t2 | table | role1
public | t3 | table | role1
3.驗證NOINHERIT
db1=> \c db1 lihao
You are now connected to database "db1" as user "lihao".
db1=# create role role2 login noinherit password '123456';
CREATE ROLE
db1=# \c db1 role2
You are now connected to database "db1" as user "role2".
db1=> create table t4 (id int);
CREATE TABLE
db1=> \d
List of relations
Schema | Name | Type | Owner
-----------+--------------------------+----------+-------
pg_temp_3 | t1 | table | role1
public | t2 | table | role1
public | t3 | table | role1
public | t4 | table | role2
經過實驗二能夠看出,從public角色上進行revoke徹底能夠實現對角色權限的控制,並且這種控制僅僅只是在當前庫下,不會對其餘庫有影響。
經過實驗一和實驗二,咱們徹底能夠得出如下結論:
數據庫中存在一個全局public角色,它不具體存在,但會影響到數據庫中已有或將有角色的權限
public就像一個public組,數據庫中全部角色默認繼承其權限
數據庫中角色繼承的權限不能僅僅對角色進行revoke,這樣是不會成功的,只有經過對其所在組的權限進行revoke纔可