PostgreSQL 中如何查看用户继承的权限

数据库关系型数据库技术服务知识库
前言

PostgreSQL 中可以使用角色来控制访问数据库对象的权限,在 PostgreSQL 中,角色在一定程度上可以等同为数据库用户或数据库用户组,同时 PostgreSQL 还允许将一个角色的权限赋予另外一个角色。本章内容将介绍如何查询用户所继承的权限。

问题复现

查看 auser 有具有对象级别的权限,可以看到用户 auser 具有表 t1 的 insert,update,delete,select 权限:

postgres=# select table_catalog,table_schema,table_name , privilege_type from information_schema.table_privileges where grantee='auser';
 table_catalog | table_schema | table_name | privilege_type 
---------------+--------------+------------+----------------
 postgres      | public       | t1         | INSERT
 postgres      | public       | t1         | SELECT
 postgres      | public       | t1         | UPDATE
 postgres      | public       | t1         | DELETE
(4 rows)
```
`
创建 buser,然后将 auser 具有的权限赋予 buser:
````undefined
postgres=# create user buser password 'RFVrfv@2022';
CREATE ROLE

postgres=# grant auser to buser;
GRANT ROLE
```
`
这里如果我们想查看 buser 有拥有的权限,使用上面的语句是查询不到的:
````undefined
postgres=# select table_catalog,table_schema,table_name, privilege_type from information_schema.table_privileges where grantee='buser';
 table_catalog | table_schema | table_name | privilege_type 
---------------+--------------+------------+----------------
(0 rows)
```
`
通过如下语句,我们可以定位到 buser 继承了 auser 的权限,不过我们还需要执行相应的查询来获取 auser 的查询,我们希望有快捷的方式来获取一个用户所继承的权限是什么。
````undefined
postgres=# SELECT r.rolname,  r.rolinherit, 
  ARRAY(SELECT b.rolname
        FROM pg_catalog.pg_auth_members m
        JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)
        WHERE m.member = r.oid) as memberof
FROM pg_catalog.pg_roles r
WHERE r.rolname='buser';
 rolname | rolinherit | memberof 
---------+------------+----------
 buser   | t          | {auser}
(1 row)

```
`
# 解决方案
PostgreSQL 提供了 **has_table_privilege()** [1] 方法来查看某个用户所继承的权限,查询语句如下:
````undefined
postgres=#  SELECT                                                                                                                      
tmp.user_name,
tmp.TABLE_NAME,
tmp.privilege_type 
FROM
(
SELECT
r.rolname AS user_name,
C.oid :: regclass AS TABLE_NAME,
P.perm AS privilege_type 
FROM
pg_class
C CROSS JOIN pg_roles r
CROSS JOIN UNNEST ( ARRAY [ 'SELECT', 'INSERT', 'UPDATE', 'DELETE', 'TRUNCATE', 'REFERENCES', 'TRIGGER' ] ) P ( perm ) 
WHERE
relkind = 'r' 
AND relnamespace NOT IN ( SELECT oid FROM pg_namespace WHERE nspname IN ( 'pg_catalog', 'information_schema' ) ) 
AND has_table_privilege ( rolname, C.oid, P.perm ) 
) tmp 
WHERE
tmp.user_name = 'buser';
 user_name | table_name | privilege_type 
-----------+------------+----------------
 buser     | t1         | SELECT
 buser     | t1         | INSERT
 buser     | t1         | UPDATE
 buser     | t1         | DELETE
(4 rows)
```
`
上述语句可以将用户所具有的对象级别的权限列出来,会方便许多。
关于 PostgreSQL 中更多关于用户权限查询语句,您可以参考文档[2]。
# 参考文档
[1] [https://www.postgresql.org/docs/current/functions-info.html](https://www.postgresql.org/docs/current/functions-info.html)
[2] [https://developer.volcengine.com/articles/7103837907202342919](https://developer.volcengine.com/articles/7103837907202342919)
**如果您有其他问题,欢迎您联系火山引擎**[技术支持服务](https://console.volcengine.com/ticket/createTicketV2/)

46
0
0
0
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论