PostgreSQL的用户权限管理

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

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

PostgreSQL权限架构是宝塔形结构

最上层是实例

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

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

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

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

image-20240205103517867

上面schema中有个奇怪的东西,public

先总结:public是缺省的权限,代表所有人的意思。

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

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

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

schema级别的权限,包括允许查看schema中的对象,允许在schema中创建对象。

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

举例来说,建了个库,又建了用户,没给这个用户赋予任何权限。缺省他就从public schema里继承了对库权限,可以连接到这个库,并且在这个库里建临时表、建表、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#列出所有的对象(table, view, sequences)
15\d
16
17#列出所有表
18\dt
19
20#列出所有索引
21\di
22
23#列出所有的角色
24\du
25#同样的sql
26select * from pg_roles;
27
28#看看能登录的用户有哪些
29select * 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中可以使用和建立的权限,注意,你现在连接的是哪个库,召回的就是哪个库的public
24#这里连的是bomsdb库,召回的就是这个库里的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);

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


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