PostgreSQL的用户权限管理

目录

公司选用了阿里云的PolarDB做数据库,这个东西其实就是Postgres增加了外挂,可以支持Oracle语法。

没办法,得仔细研究一下Postgres的用户管理了。

PostgreSQL权限架构是宝塔形结构

最上层是实例

实例中允许创建多个数据库

每个数据库中可以创建多个schema,

每个schema下面可以创建多个对象。

对象包括表、物化视图、操作符、索引、视图、序列、函数、… 等等。

image-20240205103517867

上面schema中有个奇怪的东西,public,注意:是小写。

先总结:PUBLIC是缺省的权限,代表所有人的意思(是个角色)。

默认情况下,在创建数据库之后,允许PUBLIC角色(大写)连接,即允许任何人连接。

默认情况下,数据库在创建后,不允许除了超级用户和owner所有者之外的任何人在数据库中创建schema。

默认情况下,在创建数据库之后,会自动创建名为 public 的schema,这个schema的all权限已经赋予给PUBLIC角色(注意是大写),即允许任何人在里面创建对象。

schema级别的权限,包括允许查看schema中的对象(USAGE),以及允许在schema中创建对象(CREATE)。

默认情况下新建的schema的权限不会赋予给PUBLIC角色,因此除了超级用户和owner,任何人都没有权限查看schema中的对象或者在schema中新建对象。

举例来说,建了个库,又建了用户,没给这个用户赋予任何权限。缺省他就从PUBLIC角色继承了对库里的schema.pulic权限,可以连接到这个schema.pulic,并且在这里建临时表、建表、view等等对象,但是没办法建立其它schema。

PostgreSQL的模式(SCHEMA)可以看作是一个表的集合。

一个模式可以包含视图、索引、数据类型、函数和操作符等。

再来说角色:

在数据库中所有的权限都和角色挂钩。

角色和用户的唯一区别在于,角色是nologin的,而用户允许login,仅此而已。

而"PUBLIC"是一个特殊的角色,代表着所有人。

那又有一个问题:

每个PostgreSQL对象都有一个名为“所有者”的特殊角色。只有所有者才能执行某些操作,如 ALTER TABLE ,而你不能将这样的权限授予非所有者。

那不可能只有一个人可以alter表结构吧,我们可以使用角色继承来解决此问题。创建 table_owner 角色并且 GRANT table_owner TO user1, user2 (user1和user2继承table_owner),然后赋权 ALTER TABLE my_table OWNER TO table_owner 赋予table_owner所有者角色。现在表的所有者是 table_owner 了,但是因为 user1user2 是该角色的成员,所以他们也具有继承权限来运行 ALTER TABLE了,如下图 。

image-20240205113508881

啰嗦了这么多,除了修改pg_hba.conf,赋权的命令就两条,grantrevoke,看下图:

image-20240205103610366

进入实战,首先从上到下都看一看,有什么库,有什么schema,有什么对象,有什么表,有什么索引,有什么角色:

 1#推荐用psql来进行管理,有很多快捷键,navicat里面是没有的
 2#没有的话就装一个
 3yum install postgresql.x86_64
 4
 5psql -h 10.8.2.61 -U admin 
 6
 7#必用快捷键
 8#列出所有的库
 9\l
10
11#列出所有的schema
12\dn
13
14#看schema.public权限
15\dn+ public
16
17#列出所有的对象(table, view, sequences)
18\d
19
20#列出所有的角色
21\du
22
23#列出所有表
24\dt
25
26#列出所有索引
27\di
28
29
30#同样的sql
31select * from pg_roles;
32
33#看看能登录的用户有哪些
34select * from pg_user;

那自顶向下开始:

 1#建立boms_admin角色:非超级用户+可以建立db+可以建立role+可以把权限继承给别人
 2create role boms_admin nosuperuser createdb createrole inherit;
 3
 4#建立用户,继承bomsuser的权限,可以登录,有密码
 5CREATE role bomsuser in role boms_admin login password ‘password’;
 6
 7#建立库,owner是boms_admin
 8create database bomsdb owner boms_admin;
 9
10#用新用户连接新的DB,当然也可以用超级用户连接,这两人都有权限
11\c bomsdb bomsuser;
12\c bomsdb superuser;
13
14#先建立个schema,并且在schema里建个表
15create schema zrr;
16create table zrr.test (x integer);
17insert into zrr.test values (1),(2),(3);
18select * from zrr.test;
19
20#召回PUBLIC可以在数据库级别中database test中连接、使用临时表的权限
21revoke connect, temporary on database bomsdb from public;
22
23#召回PUBLIC可以在schema级别中可以USAGE使用和CREATE建立的权限,注意,你现在连接的是哪个库,召回的就是哪个库的public
24#这里连的是bomsdb库,召回的就是这个库里的schema.public
25REVOKE USAGE, CREATE ON SCHEMA public FROM public;
26
27#这样操作之后只有owner和superuser可以用这个database了
28#我们必须显式赋权才可以连上并且建库了
29
30#建个新用户
31create user testuser login password ‘password';
32
33#赋连接权限,赋予一个表的只读权限
34grant connect on database bomsdb to testuser;
35grant usage on schema zrr to testuser;
36grant select on table zrr.test to testuser;
37
38#连接上去,测一下
39\c bomsdb testuser;
40select * from zrr.test;

两个脚本:

A、看用户test1都有啥表权限

1SELECT grantee,table_schema,table_name, string_agg( privilege_type,', ' ) as privilege_type 
2FROM information_schema.role_table_grants 
3where grantee='test1' 
4group by table_name,table_schema,grantee;

B、看表xxx都是什么用户才有权限

1SELECT grantee,table_schema,table_name,string_agg( privilege_type,', ' ) as privilege_type
2FROM information_schema.role_table_grants
3WHERE table_name='xxx'
4group by grantee,table_schema,table_name;

提示无权限的时候,可以用以下函数来检查

1select has_database_privilege(user, database, privilege);
2
3select has_schema_privilege(user, schema, privilege);
4
5select has_table_privilege(user, table, privilege);

太费劲了,花了两天时间才算大概搞明白。

再给个初始的直白解释脚本:

概念神:

一、权限管理在 PostgreSQL 中是递归和分层的,因此需要分别管理1、数据库、2、模式,3、以及模式中的具体对象(如表)。三种级别中的权限。
二、PostgreSQL 的权限模型是累加的。
 1#首先用admin登录
 2
 3#建立一个库
 4CREATE DATABASE test;
 5
 6#这时候schema.public直接就被建立了,而且PUBLIC直接赋权了
 7#这时候去\dn+ public
 8\dn+ public
 9                        List of schemas
10  Name  |  Owner  | Access privileges  |      Description
11--------+---------+--------------------+------------------------
12 public | dbadmin | dbadmin=UC/dbadmin+| standard public schema
13        |         | =UC/dbadmin        |
14#上面命令可以看到只有dbadmin是Owner,且权限是UC
15#但实际从PGadmin里面看,还有个PUBLIC UC(USAGE+CREATE)的权限,缺省就赋予了
16
17
18#下面一句虽然召回了public对库的权限,但是,建库就缺省有的PUBLIC对schema的权限不会消失
19#因为postgres的权限机制是累加机制
20#因此,你撤销了数据库层面的权限,但没有触及 public schema 本身的权限。
21REVOKE ALL ON DATABASE test FROM public;
22
23#建立角色组,并且可以连接到数据库,在库级别赋予所有权限
24#依然只会叠加,不会影响到public schema的权限
25CREATE ROLE test_project;
26GRANT CONNECT ON DATABASE test TO test_project;
27GRANT ALL PRIVILEGES ON DATABASE test TO test_project;
28
29#建立角色,把角色组的权限给角色,就搞定了
30CREATE ROLE test LOGIN PASSWORD 'lankutest';
31GRANT test_project TO test;

补充:

  • PUBLICpublic(未加引号)是等价的,在 PostgreSQL 上大小写不敏感。
  • "PUBLIC"(加双引号)会被看作是一个字符串,而非 PostgreSQL 预定义的 PUBLIC 角色。
  • PUBLIC 是 PostgreSQL 的特殊保留角色,代表所有用户,不能直接创建或管理,也不会出现在 pg_roles 中。

Openvpn 的一些问题
Voip的lsusb检测华为猫棒usb地址来回跳动
comments powered by Disqus