PostgreSQL_經過schema控制用戶權限

背景環境

schema的特色html

  • schema概念像命名空間
  • schema下不能再有schema嵌套
  • 各個對象好比表,函數等存放在各個schema下
  • 同一個schema下不能有重複的對象名字,但在不一樣schema下能夠重複

使用schema的做用sql

  • 方便管理多個用戶共享一個數據庫,可是又能夠互相獨立.
  • 方便管理衆多對象,更有邏輯性
  • 方便兼容某些第三方應用程序,建立對象時是有schema的

好比要設計一個複雜系統,由衆多模塊構成,有時候模塊間又須要有獨立性。各模塊存放單獨的數據庫顯然是不合適的。 這時候使用schema來分類各模塊間的對象,再對用戶進行適當的權限控制,這樣邏輯也很是清晰。數據庫

經常使用數據庫中的schema異同bash

大多數數據庫都有schema或者同等意義的概念,可是含義和具體操做不一樣。函數

  • PostgreSQL中,一個database下能夠有多個schema。能夠給schema指定一個owner,若是沒有指定,那麼當前用戶就是schema的默認owner。
  • 在Oracle數據庫中不能直接新建一個schema,系統在建立一個用戶的同時爲這個用戶建立一個同名的schem並做爲該用戶的缺省shcema。即schema的個數同user的個數相同,並且schema名字同user名字一一 對應而且相同。
  • 在MySQL中沒有schema,因此建立一個database的效果和創建一個schema是相同的。咱們能夠簡單的理解爲,MySQL中的database就是schema。

本次測試軟件環境以下post

CentOS 7 x64測試

PostgreSQL 11.1ui

權限矩陣

咱們須要在PostgreSQL中創建一個database,而且在這個db下創建多個schema。每一個schema有本身的owner,而且db owner能夠操做全部schema。spa

簡單的權限關係矩陣以下設計

user \ schema S00 S01 S02
db_demo_owner (db owner 主用戶) Y Y Y
schema_owner_01(子用戶) N Y N
schema_owner_02(子用戶) N N Y

初始化數據庫

Superuser建立用戶和數據庫

-- 使用superuser登陸(admin是提早創建的superuser,避免直接使用postgres)
psql --username=admin --dbname=postgres --password
複製代碼
-- 新建用戶,這個用戶將成爲Master用戶
drop user if exists db_demo_owner;
create user db_demo_owner with password 'xxx';

-- 新建一個子用戶
drop user if exists schema_owner_01;
create user schema_owner_01 with password 'xxx';

-- 經過設置權限組的方式讓主用戶擁有子用戶的權限 
-- db_demo_owner is member of schema_owner_01,即主用戶db_demo_owner擁有schema_owner_01的權限
grant schema_owner_01 to db_demo_owner;

-- 另外一個子用戶
drop user if exists schema_owner_02;
create user schema_owner_02 with password 'xxx';
grant schema_owner_02 to db_demo_owner;
複製代碼
-- 新建一個測試用DB並分配給主用戶
drop database if exists db_demo;
create database db_demo with encoding='utf8' owner=db_demo_owner;
複製代碼

主用戶建立schema(重點)

-- 主用戶登陸
psql --username=db_demo_owner --dbname=db_demo --password
複製代碼
-- 不指定schema owner,默認是當前用戶(主用戶)
drop schema s00 cascade;
create schema s00 ;	

-- 用主用戶創建schema並設置子用戶爲owner
drop schema s01 cascade;
create schema s01 authorization schema_owner_01 ;

drop schema s02 cascade;
create schema s02 authorization schema_owner_02 ;
複製代碼

主用戶建表

-- 主用戶登陸
psql --username=db_demo_owner --dbname=db_demo --password

-- 主用戶在每一個schema中建表t00
create table s00.t00(id int);
insert into s00.t00 values(1);	

create table s01.t00(id int);
insert into s01.t00 values(1);

create table s02.t00(id int);
insert into s02.t00 values(1);
複製代碼

子用戶建表

不一樣子用戶在本身的schema中建表

-- 子用戶1 登陸
psql --username=schema_owner_01 --dbname=db_demo --password 

create table s01.t01(id int);
insert into s01.t01 values(1);
複製代碼
-- 子用戶2 登陸
psql --username=schema_owner_02 --dbname=db_demo --password 

create table s02.t02(id int);
insert into s02.t02 values(1);
複製代碼

驗證Owner

確認db owner

-- 主用戶是DB Owner
postgres=# \l db_demo
                                 List of databases
  Name   |     Owner     | Encoding |   Collate   |    Ctype    | Access privileges
---------+---------------+----------+-------------+-------------+-------------------
 db_demo | db_demo_owner | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
(1 row)

-- 主用戶在子用戶組裏面,即已經擁有子用戶的權限
postgres=# \du *owner*
                          List of roles
    Role name    | Attributes |             Member of
-----------------+------------+-----------------------------------
 db_demo_owner   |            | {schema_owner_01,schema_owner_02}
 schema_owner_01 |            | {}
 schema_owner_02 |            | {}
複製代碼

確認schema owner

-- 三個schema分屬於不一樣用戶
db_demo=> \dn s*
    List of schemas
 Name |      Owner
------+-----------------
 s00  | db_demo_owner
 s01  | schema_owner_01
 s02  | schema_owner_02
(3 rows)
複製代碼

確認表owner

-- 五張表分屬於不一樣的用戶
db_demo=> \dt s*.
            List of relations
 Schema | Name | Type  |      Owner
--------+------+-------+-----------------
 s00    | t00  | table | db_demo_owner
 s01    | t00  | table | db_demo_owner
 s01    | t01  | table | schema_owner_01
 s02    | t00  | table | db_demo_owner
 s02    | t02  | table | schema_owner_02
(5 rows)
複製代碼

驗證訪問權限

子用戶

沒有單獨受權的時候,子用戶僅能訪問本身的表

-- 子用戶1 登陸
psql --username=schema_owner_01 --dbname=db_demo --password	

-- 無權限
db_demo=> select * from s00.t00;
ERROR:  permission denied for schema s00

db_demo=> select * from s02.t02;
ERROR:  permission denied for schema s02

-- 有權限
db_demo=> select * from s01.t01;
 id
----
  1
(1 row)
複製代碼

主用戶

主用戶可以訪問全部表

-- 主用戶登陸
psql --username=db_demo_owner --dbname=db_demo --password

-- 都有權限
db_demo=> select * from s00.t00;
 id
----
  1
(1 row)

db_demo=> select * from s01.t01;
 id
----
  1
(1 row)

db_demo=> select * from s02.t02;
 id
----
  1
(1 row)
複製代碼

變動schema owner

s02原來屬於owner02,如今變動爲owner01

-- 主用戶登陸
psql --username=db_demo_owner --dbname=db_demo --password

-- 變動前
db_demo-> \dn s02
    List of schemas
 Name |      Owner
------+-----------------
 s02  | schema_owner_02
(1 row)

-- 變動schema的owner到另外一個子用戶
alter schema s02 owner to schema_owner_01;

-- 變動後
db_demo=> \dn s02
    List of schemas
 Name |      Owner
------+-----------------
 s02  | schema_owner_01
(1 row)
複製代碼

重要提示:僅僅變動owner並不能修改已有表的權限,必須經過顯式賦權

-- 變動指定表owner
alter table s02.t02 owner to schema_owner_01;

-- 或者在不變動owner的狀況下,批量賦權schema下的全部表
grant all on all tables in schema s02 to schema_owner_01;
複製代碼

只讀權限

通過前面的操做,子用戶02已經沒有任何訪問權限了。咱們但願這個子用戶在全部schema都有隻讀權限。

-- 主用戶登陸
psql --username=db_demo_owner --dbname=db_demo --password

-- 重要提示:這種方式僅對已經存在的表有效。之後創建的表不會自動有隻讀權限
grant usage on schema s00, s01, s02 to schema_owner_02;
grant select on all tables in schema s00, s01, s02 to schema_owner_02;
複製代碼

若是咱們但願之後創建的全部新表均可以自動得到只讀權限(對已經存在的表無效),可使用以下語句。

官方說明在這裏

-- 對子用戶01,02之後在schema s00,s01,s02下新建的表都有效
alter default privileges 
	for user schema_owner_01, schema_owner_02 
	in schema s00, s01, s02 
	grant select on tables to schema_owner_02;
複製代碼
相關文章
相關標籤/搜索