暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

PostgreSQL用户与权限解析

原创 梧桐 2023-08-17
2505

用户概述

通用版数据库有两类用户:超级用户和普通用户;超级管理员不做权限检查;
数据库中的用户和角色不做区分,唯一的区别是login权限。
PostgreSQL没有通用用户和本地用户的区别,用户建立在实例级别,通过权限对数据库对象进行控制。

权限体系

PostgreSQL的权限体系类似Linux操作系统,有用户和组概念,集群(实例)有数据库对象集合的概念,而数据库是多模式(schema)的集合,每一个模式下又包含多个数据库对象(表、视图、序列等)。
PostgreSQL权限可以划分为:实例权限->表空间权限->数据库权限->schema权限->object权限

集群 翻译成cluster,实际上就上实例,可以理解为初始化的数据目录,如:/usr/pgsql-14/data

都有哪些权限呢?

  • 实例级权限:用户、角色、数据创建、登录以及复制;
  • 表空间权限:创建对象;
  • 数据库级权限:连接、创建方案等;
  • 方案级权限:使用方案以及在方案中创建对象;
  • 表级权限:增删改查等权限;
  • 列级权限:允许或限制对列的访问。

以上权限绝可以用grant授予,用revoke进行回收。

PostgreSQL分为系统权限和对象权限:

系统权限——针对数据库、用户、角色的权限,如连接数据库、创建数据库、创建用户等,权限包括LOGIN、PASSWORD、SUPERUSER、CREATEDB、CREATEROLE、INHERIT等。

对象权限——针对数据库对象,如表、序列、函数等客体上执行动作的权限,权限包括select、insert、update、delete、references、trigger、create、connect、temporary、execute和usage等。

角色属性信息在系统表pg_authid里。pg_roles是pg_authid公开的视图。角色之间的成员关系在pg_auth_members表里,可以通过select查阅。

特殊权限

PostgreSQL中的超级管理员相当于Oracle的sys用户,拥有数据库的所有权限,访问权限限制可以实例层面设置;另一个特殊用户是public,准确说是角色public,public角色代表所有人,当把一项权限授予public时,相当于所有用户都具备这个权限。

在Postgresql实例被初始化后,会默认默认建立一个名为postgres的超级管理员。。

在Postgresql实例被初始化之后,默认角色public拥有connect权限,可以连接到任意数据库;

在每一个数据库下,默认了一个public的schema,默认了public角色可以在public schema下创建object的权限,因此,PostgreSQL在实例被初始化之后,默认的权限是较大的,在生产环境中需要做限制。例如:收回public角色的connect权限,如下:

revoke CONNECT on DATABASE postgres from PUBLIC;

也可以收回public的所有权限,执行:

revoke ALL on DATABASE postgres from PUBLIC ;

all在数据库上的权限代表有 CREATE | CONNECT | TEMPORARY | TEMP

这样,新建一个用户之后,要使新建用户能够访问某个数据库,就需要授予connect权限,否则,新建用户是连接不了任何数据库的。
例子1:
(1)创建用户user1

create user user1 password 'steven'; CREATE ROLE

(2)使用user1连接postgres数据库

psql -U user1 -d postgres psql: FATAL: permission denied for database "postgres" DETAIL: User does not have CONNECT privilege.

收回在public 角色在public下的所有权限:

revoke ALL on SCHEMA public from PUBLIC ;

ALL代表CREATE | USAGE
收回后,用户具备连接权限,依然不能再数据库中创建任何object

例子2
(1)授予user1连接数据库postgres的权限

grant CONNECT on DATABASE postgres to user1 ;

(2)使用user1连接postgres数据库

psql -U user1 -d postgres The license due date is: 2022-10-01 00:00:00 It's commercial license. psql Type "help" for help.

(2)新建表

create table public.t1(id int); ERROR: permission denied for schema public LINE 1: create table public.t1(id int);

甚至连选择public schema的权限都没有:

create table t1(id int); ERROR: no schema has been selected to create in LINE 1: create table t1(id int);

使用管理员授予usage访问schema的权限:
grant USAGE on SCHEMA public to user1;

此时user1 有使用usage权限,但无创建权限:

create table t1(id int); ERROR: permission denied for schema public LINE 1: create table t1(id int);

再次使用管理员授予create权限

grant CREATE on SCHEMA public to user1 ;

此时user1 就具有了创建对象权限:

create table t1(id int); CREATE TABLE

有在schema上使用和创建object的权限,但不代表具备创建schema权限

create schema user1;
ERROR:  permission denied for database postgres

如果要用于创建schema权限,需要在数据库层面授予create权限。

权限解读

如果一个object对象是某一用户创建,那么用户是object的拥有者,object拥有者拥有对该object的一切权限,包括:SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER 等权限。拥有者可以将该对象的权限授予其他用户。

总结,PostgreSQL中权限含义如下:

rolename=xxxx – privileges granted to a role
=xxxx – privileges granted to PUBLIC

        r -- SELECT ("read")  
        w -- UPDATE ("write")  
        a -- INSERT ("append")  
        d -- DELETE  
        D -- TRUNCATE  
        x -- REFERENCES  
        t -- TRIGGER  
        X -- EXECUTE  
        U -- USAGE  
        C -- CREATE  
        c -- CONNECT  
        T -- TEMPORARY  
  arwdDxt -- ALL PRIVILEGES (for tables, varies for other objects)  
        * -- grant option for preceding privilege  
  
    /yyyy -- role that granted this privilege  
\z
                              Access privileges
 Schema |   Name   | Type  | Access privileges | Column privileges | Policies 
--------+----------+-------+-------------------+-------------------+----------
 public | capitals | table | postgres=arwdDxt/postgres |                   | 
 public | cities   | table | postgres=arwdDxt/postgres |                   | 
 public | t1       | table |                   |                   | 
(3 rows)

在此列表中,对于表capitals,postgres用户有插入、查询、修改、删除、截断(truncate)、REFERENCES(允许创建外键)、建触发器权限,此权限是postgres用户授予的;对于表t1,访问权限一列为空,表示只有拥有者有所有权限,其他用户(超级管理员除外)都没权限。
使用超级管理员收回t1的查询权限,如下:

revoke SELECT on TABLE t1 from user1; REVOKE \z Access privileges Schema | Name | Type | Access privileges | Column privileges | Policies --------+----------+-------+--------------------+-------------------+---------- public | capitals | table | postgres=arwdDxt/postgres | | public | cities | table | postgres=arwdDxt/postgres | | public | t1 | table | user1=awdDxt/user1 | | (3 rows) \c - user1 You are now connected to database "postgres" as user "user1". select * from t1; ERROR: permission denied for relation t1

主机认证权限

在postgres中,可以限制超级管理员登录数据库,需要修改主机认证文件pg_hba.conf,例如,这里限制超级管理员postgres从本地登录,只允许user1 登录如下:

"local" is for Unix domain socket connections only #local all all trust local postgres user1 trust 不允许超级管理员登录也可以配置为: local postgres postgres reject

发送重新读取主机认证文件给实例

pg_ctl reload -D ~/localdb01/

或者使用信号量

kill -s SIGHUP 3161

3161表示主进程编号,可以通过ps -ef|grep postgres查看

再次使用超级管理员登录会收到一下拒绝提示:

psql -U postgres -d postgres psql: FATAL: no pg_hba.conf entry for host "[local]", user "postgres", database "postgres", SSL off

使用user1登录:

psql -U user1 -d postgres The license due date is: 2021-10-01 00:00:00 It's commercial license. psql Type "help" for help.

登录数据库方式也可以在pg_hba.conf中设置,以上是使用操作系统认证,不需要密码即可登录。修改为需要使用密码登录:

#local all all trust local postgres user1 md5

再次发送信号给数据库主进程

pg_ctl reload -D ~/localdb01/ psql -U user1 -d postgres Password for user user1: The license due date is: 2021-10-01 00:00:00 It's commercial license. psql (10.0) Type "help" for help.

系统权限

系统的CREATEDB、CREATEROLE等权限,是在创建用户时或者修改用户时授予的,通过create user 、create role、alter user和alter role授予,例如帮助:

\h create user Command: CREATE USER Description: define a new database role Syntax: CREATE USER name [ [ WITH ] option [ ... ] ] where option can be: SUPERUSER | NOSUPERUSER | CREATEDB | NOCREATEDB | CREATEROLE | NOCREATEROLE | INHERIT | NOINHERIT | LOGIN | NOLOGIN | REPLICATION | NOREPLICATION | BYPASSRLS | NOBYPASSRLS | CONNECTION LIMIT connlimit | [ ENCRYPTED ] PASSWORD 'password' | VALID UNTIL 'timestamp' | IN ROLE role_name [, ...] | IN GROUP role_name [, ...] | ROLE role_name [, ...] | ADMIN role_name [, ...] | USER role_name [, ...] | SYSID uid

如果要收回用户的系统权限,可以通过alter user或者alter role,比如给user1授予创建用户权限,然后再收回:

alter user user1 createrole ;

收回权限则是:

alter user user1 nocreaterole ;

权限级联

在Oracle数据中,系统权限使用with admin option授予后,在权限收回时,不级联回收;对象权限使用 with grant option授予后,权限回收时是级联回收的。在PostgreSQL中,系统权限没有级联的概念;对象权限可以通过with grant option授予,在进行权限回收时,必须显示指定级联回收,否则提示有权限依赖,举例如下:
(1)使用超级管理员postgres创建一张表,将表的查询权限授予user1,同时允许user1将此权限授予其他用户。

create table t2(id int); CREATE TABLE
grant SELECT on TABLE t2 to user1 with grant option ; GRANT

(2)使用user1登录,user 将权限授予steven用户

\c - user1 You are now connected to database "postgres" as user "user1". grant SELECT on t2 TO steven; GRANT

(3)使用超级管理员回收user1对表t2的查询权限

\c - postgres You are now connected to database "postgres" as user "postgres". revoke SELECT on TABLE t2 from user1; ERROR: dependent privileges exist HINT: Use CASCADE to revoke them too.

必须使用cascade,才能把权限全部收回

revoke SELECT on TABLE t2 from user1 cascade; REVOKE

默认权限

通过alter default privileges 可以定义默认权限。部分语法如下:

例子:
默认把查询模式public 下所有表的权限赋予steven

alter default privileges in schema public grant select on tables to steven;
\h alter default privileges Command: ALTER DEFAULT PRIVILEGES Description: define default access privileges Syntax: ALTER DEFAULT PRIVILEGES [ FOR { ROLE | USER } target_role [, ...] ] [ IN SCHEMA schema_name [, ...] ] abbreviated_grant_or_revoke where abbreviated_grant_or_revoke is one of: GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER } [, ...] | ALL [ PRIVILEGES ] } ON TABLES TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ] REVOKE [ GRANT OPTION FOR ] { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER } [, ...] | ALL [ PRIVILEGES ] } ON TABLES FROM { [ GROUP ] role_name | PUBLIC } [, ...] [ CASCADE | RESTRICT ]

例子:
默认把查询模式public 下所有表的权限赋予steven

alter default privileges in schema public grant select on tables to steven;
最后修改时间:2025-03-12 11:19:32
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论