六、角色和用户

前面几章分别介绍了服务程序的安装、管理、登录、密码修改等信息,后面的几章就开始深入学习数据库、表等数据库内部结构和信息管理。在学习数据库内部结构之前,我们先学习PostgreSQL里的权限管理,因为后面学习的数据库大部分操作都是和用户以及权限相关联的,只有把权限搞懂了,才能理解后面各种操作的含义。

角色/用户的定义和区别

角色(role)的定义

在PostgreSQL里,角色是用来进行数据库登录和管理的一个ID。有点像是linux上的用户和群组的综合体,具有这两者的功能。
比如我们定义了一个角色dba,用来管理数据库,那么既可以通过角色dba来登录数据库,进行数据库管理。还可以将其他角色添加到dba这个角色里来。让其他角色也具有管理数据库的功能,其他角色自动继承dba的权限。
后面讲到权限的时候,我们还会说到,角色dba对某张表具有全部权限的时候,他可以把部分权限分配给角色组里的其他成员,实现精细化控制。

用户的定义,以及和角色的区别

在PostgreSQL里,角色role和用户user是一样的概念,除了名称不一样。还有一点区别就是:创建用户默认具有登录(login)权限,而创建角色默认没有登录权限。
它们的命令用户也几乎是一模一样的。下面我们一起来看。

角色/用户的管理

PostgreSQL进行角色管理的基本原则是:将数据库的表或者视图的权限赋予给某个角色,然后再将这个用户添加到这个角色中,这个用户就自动拥有了这个角色的权限。当这个用户离职时,取消其角色即可,实现了权限和用户的灵活管理。
在实际的应用中,PostgreSQL中用户也可以当作角色使用,可以把用户赋予给另外一个用户。但是尽量不要这样使用。

角色/用户管理的基本命令有:

  • 创建角色/用户 CREATE ROLE/USER
  • 删除角色/用户 DROP ROLE/USER
  • 修改角色/用户 ALTER ROLE/USER

下面我们依次来看这些命令的用法:

1. 创建角色和用户命令、删除用户和角色命令

创建角色的基本命令格式是:

CREATE ROLE/USER name [ [ with ] option [ ... ] ]
option 可以是下面的这些值:
- SUPERUSER  | NOSUPERUSER
- CREATEDB | NOCREATEDB
- CREATEROLE | NOCREATEROLE
- CREATEUSER | NOCRATEUESR
- INHERIT | NO INHERIT
- LOGIN | NOLOGIN
- REPLICATION | NOREPLICATION
- BYPASSRLS | NOBYPASSRLS
- CONNECTION LIMIT connlimit
- [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'
- VALID UNTIL 'timestamp'
- IN ROLE role_name
- IN GROUP role_name
- ROLE role_name
- ADMIN role_name
- USER role_name
- SYSID uid

命令里的name指的是角色/用户的名称,后面的选项看起来很多,但是很多选项的意义是相同的,知道了其中一个的用法,另外的也知道怎么用了。

选项含义

  • SUPERUSER | NOSUPERUSER,用来创建一个超级用户,要求创建者自己是超级用户。超级用户拥有数据库的所有权限,因此小心使用这个选项。默认是NOSUPERUSER
  • CREATEDB | NOCREATEDB 让角色拥有创建数据库的权限,默认值是NOCREATEDB
  • CREATEROLE | NOCREATEROLE 让角色有创建新角色的权限,但是新角色拥有的最大权限也不会超过它的父角色的权限。默认是NOCREATEROLE
  • CREAETEUSER | NOCREATEUSER 即将废弃的选项,允许角色创建新用户,但是这个选项和 CREATEROLE | NOCREATEROLE选项并不是对等的,区别我们在后面的示例中看。
  • INHERIT | NOINHERIT 用来确定这个角色是否继承它的父角色的权限,默认是INHERIT
  • LOGIN | NOLOGIN 是否允许角色登录,如果角色创建时带上了LOGIN选项,那么相当于是CREATE USER,角色这个选项的默认值是NOLOGIN
  • REPLICATION | NO REPLICATION 用来允许角色初始化流复制或者将系统转换为备份模式。拥有这个选项的角色权限比较高,因此只能用于特定角色上面。默认是NOREPLICATION
  • BYPASSRLS | NOBYPASSRLS 这个选项决定角色是否绕过每个行级安全策略(RLS),默认是NOBYPASSRLS。PostgreSQL数据库里的表默认是行级安全的,默认情况下只有超级用户和表的拥有者会绕过RLS。因此如果你给某个角色在某个表上有BYPASSRLS权限,那么它能够通过pg_dump命令将数据库备份出去。
  • CONNECTION LIMIT connlimit 设置这个角色的连接数限制
  • ENCRYPTED | UNENCRYPTED 控制角色密码在系统表里是否加密存储,默认值是通过配置文件里的password_encryption设置的,默认值是on,即加密。如果密码在存储数据库的时候已经是加密以后的密文,那么无论是否设置这个选项都无所谓。因为PostgreSQL无法解出密码。
  • PASSWORD password 设置角色的密码,如果你不想这个角色可以通过认证,可以将密码设置为NULL,这样任何情况下都会认证失败。
  • VALID UNTIL 'timestamp' 设置角色密码的过期时间,不设置的话,角色密码一直有效。
  • IN ROLE role_name 要将创建的新角色name 添加到角色role_name里面去,可以跟多个role_name的名称
  • IN GROUP role_nameIN ROLE一个意思
  • ROLE role_namerole_name 添加到新创建的角色name里面去,注意,这个选项和 IN ROLE选项的意思刚好相反
  • ADMIN role_name 也是将role_name添加到新创建的角色name里面去,但是role_name在新的角色里拥有添加新角色的权限。相当于把role_name设置为群组管理员,可以管理群里的用户。
  • USER role_nameROLE role_name的用法一样
  • SYSID uid 手动设置角色的ID,默认是自动分配。

如果选项全都不带的话,那么就会使用这些选项的默认值。看完了创建的命令,我们再看看删除用户和角色的命令,删除用户和角色的命令相比较之下就非常简单了。如下所示,基本命令格式是:

DROP ROLE/USER [ IF EXIST ] name [,....]

选项含义:

  • IF EXISTS 可选的选项,用于角色或用户不存在的情况,不带这个参数时,删除不存在的用户会报错。带这个参数时不会报错,但是会给出提示信息。
  • name 角色或用户的名称

选项含义详解示例

LOGIN | NOLOGIN、PASSWORD

下面我们先从简单的选项开始看起,先看LOING | NOLOGINPASSWORD这两个选项(当前以postgres这个超级用户登录和操作):

postgres=# create role dba1;        #创建一个角色dba
CREATE ROLE
postgres=# create user dba2;    #创建一个用户dba2
CREATE ROLE

从上面可以看到,创建role和user的时候,提示都是创建角色。但是创建的role和user有什么区别呢?我们来看一下:

postgres=# \password dba1;                  #修改dba1的密码
Enter new password: 
Enter it again: 
postgres=# \password dba2;                  #修改用户dba2的密码
Enter new password: 
Enter it again: 
postgres=# \q                               # 退出postgres用户
[root@cephadmin ~]# psql -U dba1      #尝试使用dba1登录
Password for user dba1: 
psql: FATAL:  role "dba1" is not permitted to log in       #这里提示角色dba1不允许登录
[root@cephadmin ~]# psql -U dba2      #尝试使用dba2登录
Password for user dba2: 
psql: FATAL:  database "dba2" does not exist          #没有提示不允许登录,但是提示数据库dba2不存在。

从上面可以看到,通过create role创建的角色是不允许登录的,这是因为CREATE ROLE命令其中一个默认值是NOLOGIN,不能登录。而CREATE USER命令创建的角色则是LOGIN,即可登录。只是因为没有给dba2配置默认的数据库,所以登录出错。我们配置好dba2的数据库看一下:

postgres=# create database dba2;    #切换回postgres用户,创建数据库dba2
CREATE DATABASE
postgres=# \q
[root@cephadmin ~]# psql -U dba2    #使用dba2用户登录。
Password for user dba2: 
psql (9.6.6)
Type "help" for help.

dba2=> \l 

可以看到此时正常登录,从这里就能看到LOGIN和NOLOGIN的区别。再看一个验证示例:

postgres=# CREATE ROLE dba3 LOGIN PASSWORD '123456'; 
CREATE ROLE
postgres=# CREATE ROLE dba4 NOLOGIN PASSWORD '123456'; 
CREATE ROLE
postgres=# \q
-bash-4.2$ psql -p 5433 -U dba3 
Password for user dba3: 
psql: FATAL:  database "dba3" does not exist
-bash-4.2$ psql -p 5433 -U dba4
Password for user dba4: 
psql: FATAL:  role "dba4" is not permitted to log in

这里我们在创建的时候直接带上了LOGINNOLOGIN这两个选项,同时还直接使用PASSWORD这个选项给角色创建初始密码。从尝试登录的结果可以看到,这个时候角色dba3可以登录,而用户dba4不能登录,和上面那个示例刚好是反的,进一步验证了这两个选项的功能。

创建的示例我们看完了,再看下删除用户的示例:

postgres=# drop role dba1; 
DROP ROLE
postgres=# drop role if exists dba1; 
NOTICE:  role "dba1" does not exist, skipping
DROP ROLE
postgres=# drop role dba1; 
ERROR:  role "dba1" does not exist
postgres=# drop role dba2; 
DROP ROLE
postgres=# drop user dba3; 
DROP ROLE
postgres=# drop user dba4; 
DROP ROLE

上面的几个删除操作把删除角色/用户的几个操作都涉及到了。我们分别来看一下:

  • 第一个使用DROP ROLE命令删除角色dba1,成功
  • 第二个使用DROP ROLE IF EXISTS命令删除角色dba1,因为已经删除过,但是又IF EXISTS子句,所以给出NOTICE
  • 第三个使用DROP ROLE命令删除角色dba1,因为已经删除过,且没有IF EXISTS判断,所以给出错误ERROR
  • 第四个使用DROP ROLE命令删除用户dba2,成功,可以看到用户和角色没有区别
  • 第五个使用DROP USER命令删除角色dba3,成功,同样说明用户和角色没有区别
  • 第六个使用DROP USER命令删除用户dba4,成功。
SUPERUSER、CREATEDB、CREATEROLE

我们再接着看和数据库、表以及角色相关的选项,如下所示:

  • SUPERUSER | NOSUPERUSER —— 超级用户
  • CREATEDB | NOCREATED —— 拥有创建数据库的权限
  • CREATEROLE | NOCREATEROLE —— 拥有管理其他角色的权限

这些权限都可以在创建角色时,附加到对应的角色上面。我们从最简单的示例开始,依次创建各个等级的角色

  1. 创建可管理其他角色的角色。
#创建一个角色dba2,带上CRATE ROLE 和 LOGIN选项
postgres=# create role dba2 createrole login password '123456';    
CREATE ROLE
postgres=# \q
#使用dba2这个角色登录,可以成功登录。
[root@cephadmin ~]# psql -U dba2
Password for user dba2: 
psql (9.6.6)
Type "help" for help.

#使用dba2这个角色创建新的角色dba22,并设置账号密码
dba2=> create role dba22 login password '123456';
CREATE ROLE

# 创建拥有createrole权限的角色dba23
dba2=> create role dba23  createrole login; 
CREATE ROLE

#使用dba2这个角色创建dba22的数据库,提示权限不足。
dba2=> create database dba22;
ERROR:  permission denied to create database
dba2=> \q
[root@cephadmin ~]# psql -U dba22
Password for user dba22: 
psql: FATAL:  database "dba22" does not exist

#删除创建的两个子角色
dba2=> drop role dba22; 
DROP ROLE
dba2=> drop role dba23; 
DROP ROLE

从上面的示例中可以总结如下,具有createrole权限的角色:

  • 可以创建新的角色(例如dba22)
  • 同时也创建具有createrole权限角色(例如dba23)
  • 但是不能为自己创建的子角色创建数据库(例如无法创建数据库dba22)
  • 可以删除自己创建的子角色。
  1. 创建具有createdb权限的角色
#创建具有createdb权限的角色dba3
postgres=# create role dba3 createdb login password '123456';
CREATE ROLE

#为角色dba3创建数据库dba3
postgres=# create database dba3;
CREATE DATABASE
postgres=# \q

#使用角色dba3登录,可以正常登录
[root@cephadmin ~]# psql -U dba3;
Password for user dba3: 
psql (9.6.6)
Type "help" for help.

#在角色dba3下尝试创建其他角色,提示操作被拒绝
dba3=> create role dba33 createrole login password '123456';
ERROR:  permission denied to create role
dba3=> create role dba33 login password '123456';
ERROR:  permission denied to create role

#尝试创建数据库dba33,创建成功
dba3=> create database dba33;
CREATE DATABASE
dba3=> \l dba33;
                            List of databases
 Name  | Owner | Encoding |   Collate   |    Ctype    | Access privileges 
-------+-------+----------+-------------+-------------+-------------------
 dba33 | dba3  | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
(1 row)

#删除创建的数据库dba33,删除成功。
dba3=> drop database dba33;
DROP DATABASE
dba3=> \q

从上面的示例中可以看出,具有createdb权限的角色:

  • 具有创建数据库的权限(例如创建数据库dba33)
  • 没有创建角色的权限(例如无法创建子角色dba33)

综合上面两个示例,我们可以看到,如果我们想一个角色具有创建数据库以及创建角色的权限,那么它必须要同时拥有createdbcreaterole这两个权限。

  1. 创建具有superuser选项的角色
    superuser角色是拥有超级权限的角色。默认情况下只有postgres用户拥有此权限。因此,当postgres设置其他角色为superuser后,也会具有postgres拥有的所有权限。因此这个权限一定要谨慎设置。
#创建一个超级用户角色dba4,设置为可登录,密码123456
postgres=# create role dba4 superuser login password '123456';
CREATE ROLE

#创建数据库dba4
postgres=# create database dba4;
CREATE DATABASE
postgres=# \q

#使用dba4角色登录
[root@cephadmin ~]# psql -U dba4
Password for user dba4: 
psql (9.6.6)
Type "help" for help.

#使用dba4创建拥有createrole选项的角色dba44,设置密码为123456
dba4=# create role dba44 createrole password '123456';
CREATE ROLE

#使用dba4创建拥有createdb选项的角色dba45,设置密码为123456
dba4=# create role dba45 createdb password '123456';
CREATE ROLE

#创建数据库dba44
dba4=# create database dba44;
CREATE DATABASE

#创建数据库dba45
dba4=# create database dba45;
CREATE DATABASE

从上面的示例中可以看到:

  • 超级用户具有上面几种角色的所有权限

到这里就说完了接近一半选项的作用,下面我们继续看。

IN ROLE/IN GROUP、ROLE/USER、ADMIN、INHERIT、VALID UNTIL、CONNECTION LIMIT、ENCRYPTED 、SYSID

最后这一段的要将的比较多,但是比较重要的还是前面几个。后面的VALID UNTIL、CONNECTION LIMMIT、ENCRYPTED、SYSID不是特别重要或者说使用的不是很多,可能就简单说明一下。

这里先说一下IN ROLEIN GROUPROLEUSER这四个选项,前面两个作用是将新创建的角色添加到以有的某个角色中,同时新创建的角色会自动继承(INHERIT)已有的这个角色的所有权限,和INHERIT这个选项紧密关联。后面连个关键字的作用是,将已有的角色添加到新创建的角色中,和前两个关键字作用相反,但是也是涉及到权限的继承问题,这里把它们放到一起讲。但是因为这里涉及到了权限的问题,那么我需要在后面权限的内容学习完了以后,再来讲这几个选项的作用,这样更便于理解。此外,ADMIN这个选项也是和权限相关的,也放到后面讲。

那么我们剩下需要说的就只剩下VALID UNTIL、CONNECTION LIMIT 、ENCRYPTED、SYSID这四个选项了。

首先来说说VALID UNTIL,后面跟一个日期字符串,用来设置角色或者用户的密码过期日期,当服务器时间超过这个日期时,再登录就会提示密码错误,即使密码是对的也会提示。如果登录时认证方式设置的是trust,那么这个选项无效。如果不使用这个选项,那么默认密码一直有效。

CONNECTION LIMIT是用来设置角色可以创建的连接数,0表示禁止连接,-1表示不限制数量。其他数字表示对应的连接数。

ENCRYPTED表示给用户密码加密,而SYSID表示手动设置角色或用户的系统ID,这里也不过多赘述了。后面我们就开始看权限的内容,权限的知识了解完毕后,就结合权限知识把上面没有讲到的4个选项一起讲解一下。

2. 查看当前角色的命令有2个,分别是:
postgres=# \du 
                                   List of roles
 Role name |                         Attributes                         | Member 
of 
-----------+------------------------------------------------------------+--------
 dbuser    |                                                            | {}
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

postgres=# select rolname from pg_roles;
      rolname      
-------------------
 pg_signal_backend
 postgres
 dbuser
(3 rows)

第一个\du是psql的元命令,第二个是SQL语句。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,598评论 18 139
  • 一、源题QUESTION 36Your database is open and the LISTENER lis...
    猫猫_tomluo阅读 1,210评论 0 2
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,479评论 25 707
  • http://www.cnblogs.com/zhoujinyi/p/4610050.html 创建用户,用户是跟...
    bbmm阅读 1,127评论 0 0
  • 一场寒流乍起 双眼望穿秋裤 今年的冬天像个扭捏的小姑娘 出来露了一下脸又羞怯地缩了过去 11月的天气就这么在冬夏寒...
    魔旅行阅读 431评论 0 0