Postgresql数据库角色创建登录详解

2023-02-21 12:02:25 创建 角色 详解

角色

PG中使用角色(role)机制来解决用户身份认证。拥有登陆数据库权限的角色称之为可登录角色(login role)。一个角色可以继承其他角色的权限从而成为其成员角色;拥有成员角色的角色称为组角色。(一个组角色可以是另一个组角色的成员角色,并且这种角色之间的继承关系可以无限多层,但除非你非常有把握,否则别这么折腾自己)拥有登录权限的组角色称为可登录的组角色。然而,基于安全性的考虑,管理员呢一般是不会给组角色登陆权限的。一个角色还可以被授权于超级用户权限,但是此种授权要谨慎。

PG在最近的版本已经不再使用“用户”和“组”这两个术语,别人可能还会用,你就记住,用户代表可登录角色,组代表组角色就好。当然,PG为了保持前向兼容,create user和create group 这两个命令在当前版本中也是支持的,但与时俱进嘛,最好不要使用他们,请使用create role。

创建可登录角色

在PG安装的过程中的数据初始化阶段,系统是会默认创建一个名为postgres的可登录角色(同时会创建一个名为postgres的同名databases)。你可以通过前面文章介绍过的ident或者peer身份验证机制来将操作系统的root用户映射到数据库的postgres角色,这样就可以实现root用户免密登陆,当然或者通过设置trust模式的效果也是一样。数据库安装完成的第一件事就是用psql或者pgadmin工具以postgres角色身份登陆,然后创建其他已经规划好的角色。

?创建具备登陆权限的角色

CREATE ROLE leo LOGIN PASSWord 'mimajiushiwo'  VALID UNTIL  'infinity'  CREATEDB;

VALID子句是可选的,其功能是为此角色的权限设定的有效期,如果不写则该角色永久有效,CREATEDB 子句表明为此角色赋予了创建新数据库的权限。

?创建具备超级用户权限的角色

CREATE ROLE regina LOGIN PASSWORD 'queen' VALID UNTIL '2023-2-17 00:00' SUPERUSER;

上面的两个例子中我们创建的都是可登录的角色,如果创建不可登录的角色,省略掉LOGIN PASSWORD 子句既可。

创建组角色

一般是不应该授予组角色登录权限,但是你想,也不是不可以。

?以下的SQL创建组角色

CREATE ROLE zujuese INHERIT;

注意这个关键词INHERIT的用法。他表示组角色zujuese的任何一个成员角色都将自动继承其除“超级用户权限”外的所有权限。如果不写

INHERIT,默认也会有INHERIT的效果。

如果希望禁止组角色将其权限授予成员角色,加上NOINHERIT关键字。

?以下语句可以为组角色添加成员角色

GRANT zujuese TO leo;
GRANT zujuese TO regina;

我们之前提到过SUPERUSER超级用户权限是没有办法被继承的,然而成员角色却可以通过SET ROLE命令来实现“冒名顶替”其组角色的身份,从而获得其父角色所拥有的SUPERUSER权限,当然这种冒名顶替的状态是有期限的,仅限于当前会话存续期间有效。

举例如下:

我们呢先给zujuese超级用户权限:

ALTER ROLE zujuese SUPERUSER;

上面这个leo是zujuese的成员角色,也继承了绝大多数的权限,但leo登陆后依然不具备SUPERUSER权限。但是呢,我们只要执行以下语句就可以获得SUPERUSER权限:

SET ROLE zujuese;

我在下面才想明白这个问题:这个口令的意思是,leo扮演了zujuse在这个角色,虽然leo是zujuese的成员角色,但是superuser这个权限是没有被通过默认的赋权方式赋予的,此时set role一执行,就表示leo现在扮演了zujuese,所以才有了superuser权限

但是这种方式获得的SUPERUSER权限仅仅在会话存续期间有效。

虽然这个操作逻辑看起来好像很傻很呆 ,但是如果你不希望登录到以superuser身份犯下一些无法挽回的错误,那么这个方法是值得你考虑的。

所有的用户都可以使用SET ROLE这个命令,但是还有一个比它更加强大的命令:SET SESSioN AUTHORIZATION ,该命令只允许具备superuser权限的用户执行。为了便于理解呢,我们先介绍两个postgresql中的全局变量:current_user和session_user。执行下面的语句,我们就可以看到在这两个变量值。

SELECT session_user ,current_user;

首次登陆后,这两个值相同。执行set role就会修改current_user的值,要是执行SET SESSION AUTHORIZATION 就会同时改变current_user和session_user的值。

以下是set role命令的主要特点。

  • set role无须superuser 权限既可执行。
  • set role会修改current_user变量的值,但不会修改session_user的值。
  • 一个具备superuser权限的session_user同名角色可以通过set role设置为任何用户。
  • 非超级用户可以通过set role 设置为session_user同名角色或者其所属的组用户。
  • set role命令可以让执行角色获取到所“扮演”角色的全部权限,当然除了,set role 和SET SESSION AUTHORIZATION权限。

SET SESSION AUTHORIZATION是比set role 更为强大的命令,其关键特性如下:

  • 只有超级用户才可以执行SET SESSION AUTHORIZATION
  • SET SESSION AUTHORIZATION在整个会话存续期间都是有效的,也就是说及时超级用户通过SET SESSION AUTHORIZATION来扮演了一个非超级用户,只要会话未中断,都可以在上面再次执行SET SESSION AUTHORIZATION命令的。
  • SET SESSION AUTHORIZATION会将current_user和session_user修改为要扮演的角色。
  • 具备超级用户权限的session_user同名角色可以通过set role 来扮演任何其他角色。

下面呢,我们就展示一波:

?

psql -U leo -d postgres
SELECT session_user ,current_user;

 set role zujuese; 
SELECT session_user ,current_user;

alter role leo superuser;
set role regina ;
SELECT session_user ,current_user;

set session authorization regina;

为啥这个不成功呢,这就是我们上面说的set role的特点,是有了全部权限,但是set role和set session authorization权限是没有的。

所以我们退出后,再用leo登陆:

这说明什么呢,这说明我们上次扮演的时候给我们赋予的superuser权限是会话结束还是生效的

所以我们这波set session authorization直接就是成功了。

以上就是Postgresql数据库角色创建登录详解的详细内容,更多关于Postgresql角色创建登录的资料请关注其它相关文章!

相关文章