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;
复制代码
相关文章
相关标签/搜索