VastbaseG100

基于openGauss内核开发的企业级关系型数据库。

Menu

行级访问控制

功能描述

行级访问控制(Row Level Security)特性将数据库访问控制精确到数据表行级别,使数据库达到行级访问控制的能力。不同用户执行相同的SQL查询操作,读取到的结果是不同的。

行级访问控制的目的是控制表中行级数据可见性,通过在数据表上预定义Filter,在查询优化阶段将满足条件的表达式应用到执行计划上,影响最终的执行结果。

注意事项

  • 行级访问控制策略仅可以应用到SELECT、UPDATE和DELETE操作,不支持应用到INSERT和MERGE操作。
  • 支持对行存表、行存分区表、列存表、列存分区表、复制表、unlogged表、hash表定义行级访问控制策略,不支持外表、临时表定义行级访问控制策略。
  • 不支持对视图定义行级访问控制策略。
  • 同一张表上可以创建多个行级访问控制策略,一张表最多允许创建100个行级访问控制策略。
  • 初始用户和系统管理员不受行级访问控制策略的影响。
  • 对于设置了行级访问控制策略的表,需要谨慎授予其他用户对该表的trigger权限,以免其他用户利用触发器绕过行级访问控制策略。

配置方法

用户可以在数据表创建行访问控制(Row Level Security)策略,详情参考SQL语法CREATE ROW LEVEL SECURITY POLICY。该策略是指针对特定数据库用户、特定SQL操作生效的表达式。当数据库用户对数据表访问时,若SQL满足数据表特定的Row Level Security策略,在查询优化阶段将满足条件的表达式,按照属性(PERMISSIVE | RESTRICTIVE)类型,通过AND或OR方式拼接,应用到执行计划上。

示例

1、 以操作系统用户vastbase登录数据库主节点。

2、 连接数据库。

数据库安装完成后,默认生成名称为vastbase的数据库。第一次连接数据库时可以连接到此数据库。

执行如下命令连接数据库。

vsql -d vastbase -p 5432

3、创建用户alice, bob, peter 。

CREATE USER alice PASSWORD 'Vastbase@123'; 
CREATE USER bob PASSWORD 'Vastbase@123'; 
CREATE USER peter PASSWORD 'Vastbase@123'; 

4、创建表all_data,包含不同用户数据信息 。

CREATE TABLE all_data(id int, role varchar(100), data varchar(100)); 

5、向数据表插入数据 。

INSERT INTO all_data VALUES(1, 'alice', 'alice data'); 
INSERT INTO all_data VALUES(2, 'bob', 'bob data'); 
INSERT INTO all_data VALUES(3, 'peter', 'peter data'); 

6、将表all_data的读取权限赋予alice,bob和peter用户 。

GRANT SELECT ON all_data TO alice, bob, peter; 

7、打开行访问控制策略开关 。

ALTER TABLE all_data ENABLE ROW LEVEL SECURITY; 

8、创建行访问控制策略,当前用户只能查看用户自身的数据 。

CREATE ROW LEVEL SECURITY POLICY all_data_rls ON all_data USING(role = CURRENT_USER); 

9、查看表详细信息 。

\d+ all_data 

结果显示如下:

                         Table "public.all_data"
 Column |     Type     | Modifiers | Storage  | Stats target | Description 
--------+--------------+-----------+----------+--------------+-------------
 id     | integer      |           | plain    |              | 
 role   | varchar(100) |           | extended |              | 
 data   | varchar(100) |           | extended |              | 
Row Level Security Policies:
    POLICY "all_data_rls" FOR ALL
      TO public
      USING (((role)::name = "current_user"()))
Has OIDs: no
Options: orientation=row, compression=no, fillfactor=80, enable_rowsecurity=true

10、验证效果,切换至用户alice,执行SQLSELECT * FROM public.all_data

\c - alice
SELECT * FROM public.all_data; 

当结果显示如下信息,则表示行级访问控制生效。

 id | role  |   data 
----+-------+------------ 
 1 | alice | alice data 
(1 row) 

11、查询语句执行计划。

EXPLAIN(COSTS OFF) SELECT * FROM public.all_data; 

结果显示如下,可以看到通过rolename进行过滤。

                           QUERY PLAN
----------------------------------------------------------------
 Seq Scan on all_data
   Filter: ((role)::name = 'alice'::name)
 Notice: This query is influenced by row level security feature
(3 rows)

12、验证结果,切换至用户peter,执行SQLSELECT * FROM public.all_data

\c - peter
SELECT * FROM public.all_data; 

当结果显示如下信息,则表示行级访问控制生效。

 id | role  |   data 
----+-------+------------ 
 3 | peter | peter data 
(1 row) 

13、查询语句执行计划。

 EXPLAIN(COSTS OFF) SELECT * FROM public.all_data; 

结果显示如下,可以看到通过rolename进行过滤。

                           QUERY PLAN
----------------------------------------------------------------
 Seq Scan on all_data
   Filter: ((role)::name = 'peter'::name)
 Notice: This query is influenced by row level security feature
(3 rows)