六、角色和用户

作者: shark_tear | 来源:发表于2017-11-27 17:20 被阅读0次

    前面几章分别介绍了服务程序的安装、管理、登录、密码修改等信息,后面的几章就开始深入学习数据库、表等数据库内部结构和信息管理。在学习数据库内部结构之前,我们先学习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语句。

    相关文章

      网友评论

        本文标题:六、角色和用户

        本文链接:https://www.haomeiwen.com/subject/kbxfbxtx.html