暂无图片
暂无图片
2
暂无图片
暂无图片
暂无图片

我好像又一次搞懂了pg系的权限

一、引言

“每看一次PostgreSQL数据库的权限体系,就感觉自己搞懂了,对于PostgreSQL的权限体系控制,我简直强的可怕!但每次实践的时候却发现PostgreSQL的权限的不受控又一次把我按在地上摩擦!”

二、 背景

电科金仓数据库(原“人大金仓数据库”),是典型的PostgreSQL系数据库,其权限体系和使用方式和PostgreSQL数据库极为相似,所以我以电科金仓数据库为例,通过创建一个只读用户的方式,来帮助理解pg系权限的相关内容,总结一个标准授权流程。

三、数据库权限基本概念

从方便对PostgreSQL数据库权限体系理解的层面划分,我们可以把PostgreSQL数据库的数据库对象分为以下几类:
1)用户;

2)数据库;

3)SCHEMA;

4)OBJECT对象(表、索引、函数、序列等);

当我们想要对某个对象进行权限控制的时候,我们则必须按层级进行授权,即

1.先获取数据库的连接、使用权限(UC);

2.获取schema的连接使用权限(UC);

3.获取具体对象的具体权限(增删改查);

四、案例-创建数据库用户及只读用户

这里通过一个标准案例来帮助我们对PostgreSQL授权过程进行了解。

场景及目标:

1.创建一个wxdb的数据库;

2.为wxdb数据库创建一个wxtest的schema;

3.创建个wx用户,该用户为wxdb和wxtest的所属用户;

4.创建一个readonly用户,该用户能够对wxdb的wx用户的wxtest的schema中所有表只读权限。同时,通过wx在test的schema下新建的表被继承只读权限。

01. 创建wxdb数据库

--连接数据库
ksql test system;
--创建wxdb数据库
create database wxdb;
复制

02. 回收public对wxdb的相关权限

--该动作主要是为了保证wxdb的安全,避免其他用户可以通过public的schema连接wxdb
revoke all on DATABASE wxdb FROM PUBLIC ;
(revoke all on SCHEMA public FROM PUBLIC;)
复制

03. 创建wxtest的schema

--使用system用户连接wxdb
\c wxdb
--创建wxtest的schema
create schema wxtest;
复制

04. 创建wx的用户并允许wx连接wxdb,并将wxtest的连接和使用schema权限赋予wx

--创建wx用户
create user wx password 'Wx_123456#';
--为wx赋予wxdb数据库的连接权限
grant connect on database wxdb TO wx;
--查看数据库信息及权限
\l+
 wxdb      | system | UTF8     | zh_CN.UTF-8 | zh_CN.UTF-8 | system=CTc/system   +| 14 MB   | sys_default | 

           |        |          |             |             | wx=c/system         +|         |             | 

           |        |          |             |             | readonly=c/system    |         |             | 
 
--赋予wxtest的所有权限给用户wx
grant all on SCHEMA wxtest TO wx;
--查看wxtest的权限信息
\dn+
 wxtest           | system | system=UC/system +| 

                  |        | wx=UC/system     +| 


复制

05.创建readonly用户

create user readonly password 'Readonly_123456#';
复制

06.为readonly用户赋予wxdb的连接权限

grant usage on database wxdb to readonly;
--查看wxtest的权限信息
 \dn+
 wxtest           | system | system=UC/system +| 

                  |        | wx=UC/system     +| 

                  |        | readonly=U/system | 

复制

07.通过wx在wxtest下创建test表:

\c wx wxdb
--设置schema
set search_path=wxtest;
--创建test表
create table test(id number);
复制

08.在readonly用户中查询该表

\c wxdb readonly
set search_path=wxtest;
--查看表
\d
             关联列表

 架构模式 | 名称 |  类型  | 拥有者 

----------+------+--------+--------
 wxtest   | test | 数据表 | wx

--查询该表
select count(*) from test;
ERROR:  permission denied for table test
复制

可以发现,此时没有test表的查询权限。

09.为readonly赋予所有表的查询权限:

\c wxdb wx
--给readonly用户赋予wxtest下表的选择权限
grant SELECT ON all tables in schema wxtest TO readonly;
复制

10.再次对readonly用户中查询该表

\c wxdb readonly
set search_path=wxtest;
\d
             关联列表

 架构模式 | 名称 |  类型  | 拥有者 
----------+------+--------+--------
 wxtest   | test | 数据表 | wx 

select count(*) from test;
 count 

-------

     1

(1 行记录)
复制

此时,可以看到,我们已经可以查询test表了。

11.我们再在wxdb中通过wx创建一张新表

\c wxdb wx
create table test1(id number);
--查看wxdb下的表
\d
              关联列表

 架构模式 | 名称  |  类型  | 拥有者 
----------+-------+--------+--------
 wxtest   | test  | 数据表 | wx
 wxtest   | test1 | 数据表 | wx
复制

12.在readonly用户中查询该表

\c wxdb readonly
您现在以用户名"readonly"连接到数据库"wxdb"。
set search_path=wxtest;
--查看wxdb下的表
\d
              关联列表

 架构模式 | 名称  |  类型  | 拥有者 

----------+-------+--------+--------
 wxtest   | test  | 数据表 | wx
 wxtest   | test1 | 数据表 | wx
(2 行记录)
wxdb=> select count(*) from test1;
ERROR:  permission denied for table test1
复制

此时,可以发现,我们新创建的test1没有继承读取权限。如果我们想让readonly查看test1表,则需要再给readonly赋予一次select all tables权限(或者单独这张表的权限)。

\c wxdb wx
set search_path=wxtest;
--赋予权限
grant select ON all TABLES IN SCHEMA wxtest to readonly;
(grant select on TABLE wxtest.test1 TO readonly;)
--切换用户
\c wxdb readonly
wxdb=> set search_path=wxtest;
SET
wxdb=> \d
              关联列表
 架构模式 | 名称  |  类型  | 拥有者 
----------+-------+--------+--------
 wxtest   | test  | 数据表 | wx
 wxtest   | test1 | 数据表 | wx
(2 行记录)

wxdb=> select count(*) from test1;
 count 
-------
     0

(1 行记录)
复制

为了方便整体的授权,我们希望在新创建表后,readonly用户也可以有读取的权限。因此,可以通过alter default privileges的方式来设置全局的权限给指定用户。那么,我们模拟一下授权操作(这里我们分别用管理员和数据库所属所属用户的两种方式来)。

方式一:管理员用户赋权

--通过system管理员连接数据库
ksql wxdb system
--进行授权
alter default privileges in schema wxtest  grant select on tables to readonly;
--切换所属用户
\c wxdb wx
--创建表
create table test2(id number);
--查看表
wxdb=> \d
              关联列表

 架构模式 | 名称  |  类型  | 拥有者 
----------+-------+--------+--------
 wxtest   | test  | 数据表 | wx
 wxtest   | test1 | 数据表 | wx
 wxtest   | test2 | 数据表 | wx

--切换用户
\c wxdb readonly
set search_path=wxtest;
wxdb=> \d
              关联列表
 架构模式 | 名称  |  类型  | 拥有者 
----------+-------+--------+--------
 wxtest   | test  | 数据表 | wx
 wxtest   | test1 | 数据表 | wx
 wxtest   | test2 | 数据表 | wx
(3 行记录)

--查询表
wxdb=> select * from test2;
ERROR:  permission denied for table test2
复制

此时可以发现,我们依然没有新建表的读取权限,也就是说alter default privilege的授权没有生效!

那么我们试一下方式二:

--通过wx用户连接wxdb数据库
\c wxdb wx
set search_path=wxtest;
wxdb=> \d
              关联列表
 架构模式 | 名称  |  类型  | 拥有者 
----------+-------+--------+--------
 wxtest   | test  | 数据表 | wx
 wxtest   | test1 | 数据表 | wx
 wxtest   | test2 | 数据表 | wx
(3 行记录)
--进行授权
alter default privileges in schema wxtest  grant select on tables to readonly;
--创建表
create table test3(id number);
--查看表
wxdb=> \d
              关联列表
 架构模式 | 名称  |  类型  | 拥有者 
----------+-------+--------+--------
 wxtest   | test  | 数据表 | wx
 wxtest   | test1 | 数据表 | wx
 wxtest   | test2 | 数据表 | wx
 wxtest   | test3 | 数据表 | wx
 
--切换用户
\c wxdb readonly
set search_path=wxtest;
wxdb=> \d
              关联列表
 架构模式 | 名称  |  类型  | 拥有者 
----------+-------+--------+--------
 wxtest   | test  | 数据表 | wx
 wxtest   | test1 | 数据表 | wx
 wxtest   | test2 | 数据表 | wx
 wxtest   | test3 | 数据表 | wx
(4 行记录)

--查询表
select * from test3;
 id 
----
(0 行记录)
复制

此时,发现新建表test3可以正常查询。

也就是说,当我们需要对数据库中的对象实现权限继承的时候,我们必须要通过该库及相应的schema的所有权限用户赋权才能生效,而直接用system这样的管理权限则无法生效。

四、 归纳总结

通过上述的案例,我们可以对金仓数据库(PostgreSQL系数据库)的授权操作做出以下流程归纳,作为后续的标准权限分配流程,从而达到最小化权限控制:

序号 操作 命令
1 创建数据库,如wxdb create database wxdb;
2 在数据库下创建schema,如wxtest create schema wxtest;
3 创建schema同名用户,如wxtest create user wxtest password ‘Wxtest_123$’;
4 回收public相关权限 revoke connect on database wxdb from PUBLIC;
revoke all on schema wxtest from PUBLIC;
revoke usage on schema public from PUBLIC;
5 给schema同名用户分配权限 grant connect on database wxdb to wxtest;
grant usage on schema wxtest to wxtest;
(grant all on schema wxtest to wxtest;)
6 创建其他用户,如test create user test password ‘Test_123$’;
7 根据需求给其他用户分配权限,如增删改查 grant connect on database wxdb to test;
grant usage on schema wxtest to test;
8 权限继承分配,如增删改查 \c wxdb wxtest
set search_path=wxtest;
读取表 alter default privileges in schema wxtest grant select on tables to test;
删除表 alter default privileges in schema wxtest grant delete on tables to test;
插入表 alter default privileges in schema wxtest grant insert on tables to test;
更新表 alter default privileges in schema wxtest grant update on tables to test;
truncate表 alter default privileges in schema wxtest grant update on tables to test;
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论

目录
  • 一、引言
  • 二、 背景
  • 三、数据库权限基本概念
  • 四、案例-创建数据库用户及只读用户
    • 01. 创建wxdb数据库
    • 02. 回收public对wxdb的相关权限
    • 03. 创建wxtest的schema
    • 04. 创建wx的用户并允许wx连接wxdb,并将wxtest的连接和使用schema权限赋予wx
    • 05.创建readonly用户
    • 06.为readonly用户赋予wxdb的连接权限
    • 07.通过wx在wxtest下创建test表:
    • 08.在readonly用户中查询该表
    • 09.为readonly赋予所有表的查询权限:
    • 10.再次对readonly用户中查询该表
    • 11.我们再在wxdb中通过wx创建一张新表
    • 12.在readonly用户中查询该表
  • 四、 归纳总结