关键字:
人大金仓、KingbaseES、视图权限、视图行级权限、security definer、security invoker、bequeath current_user、bequeath definer、security_invoker、行级安全策略
1. 定义
视图定义者(DEFINER):
一般是视图的创建者,即创建视图时使用的用户或角色。但在有些数据库中可以指定DEFINER参数,那样视图定义者和创建视图时的用户可能不一致。
视图创建者 :
创建视图时使用的用户或角色。
视图所有者(OWNER):
视图的属主,一般情况下即视图的创建者。视图创建后可能会变更owner。
视图使用者:
访问视图时使用的用户或角色。
行级安全策略:一条策略授予权限以选择、插入、更新或者删除匹配相关策略表达式的行。 现有的表行会按照 USING 中指定的表达式进行检查,而将要通过 INSERT 或 UPDATE 创建的新行会按照 WITH CHECK 中指定的表达式进行检查。 当 USING 表达式对于一个给定行返回真时,该行对用户可见,而返回假或空时该行不可见。当一个 `` WITH CHECK``表达式对一行返回真时,该行会被插入或更新,而如果返回假或空时会发生一个错误。
2. 视图支持使用者权限功能描述
用户访问视图时,会通过视图访问到视图定义中用到底层的表、视图数据库对象,在对低层对象的访问权限检查时应能以指定的身份去检查。具体表现如下:
- 当视图权限检查的方式指定为使用者方式时,对视图底层的数据库对象访问权限以访问视图的用户身份去检查。
- 当视图权限检查的方式指定为定义者方式时,对视图底层的数据库对象访问权限以视图的所有者(owner)的身份去检查。
- 当未指定权限检查方式时,对视图底层的数据库对象访问权限以视图的所有者(owner)的身份去检查。
- 权限检查方式仅作用于对本视图底层的表和视图访问权限。视图本身的访问权限不受其影响。对于视图嵌套视图的情景,每个嵌套层次都应根据当前层视图制定的权限检查方式执行。
- 权限检查影响视图的访问方式有:SELECT、DELETE、INSERT、UPDATE
- 不影响超级用户的原有行为,本特性所指视图不包括物化视图,视图重编译后保留原来的权限检查方式。
3. 视图支持行级安全策略功能描述
创建视图时如果指定以视图使用者身份做权限检查,视图的基表有行级安全策略,策略将作用于对视图的查询结果。
创建视图时如默认或指定以视图定义者身份做权限检查,视图的基表有行级安全策略,策略不影响对视图的查询结果。
4. 不同模式下视图使用者权限语法介绍
- Oracle模式
- 创建视图
蓝色字体为新增子句
CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] [ RECURSIVE ] [ FORCE ] VIEW name [ ( column_name [, ...] ) ]
[ WITH ( view_option_name [= view_option_value] [, ... ] ) ]
[BEQUEATH {CURRENT_USER|DEFINER}]
AS query
[ WITH [ CASCADED | LOCAL ] CHECK OPTION | READ ONLY ]
BEQUEATH关键字后面跟视图的权限检查方式,可取值为CURRENT_USER、DEFINER,大小写不敏感,取其他值时应报错。如不指定则使用DEFINER作为默认值。
指定为CURRENT_USER时,视图访问基表和底层视图检查权限时使用视图访问者的身份。
指定为DEFINER时,视图访问基表和底层视图检查权限时使用视图定义者(owner)的身份。
- 修改视图
ALTER VIEW [ IF EXISTS ] name [BEQUEATH {CURRENT_USER|DEFINER}]
修改视图的权限检查方式,BEQUEATH意义及取值同创建视图。
2. PG模式
- 创建视图
蓝色字体为新增子句
CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] [ RECURSIVE ] [ FORCE ] VIEW name [ ( column_name [, ...] ) ]
[ WITH ( view_option_name [= view_option_value] [, ... ] ) ]
AS query
[ WITH [ CASCADED | LOCAL ] CHECK OPTION | READ ONLY ]
新增view_option_name
security_invoker ( boolean ) 取值为true或者false. 大小写不敏感,取其他值时应报错。
当取值为true时,视图访问基表和底层视图检查权限时使用视图访问者的身份。
当取值为false时,视图访问基表和底层视图检查权限时使用视图定义者(owner)的身份。
- 修改视图
ALTER VIEW [ IF EXISTS ] name SET ( view_option_name [= view_option_value] [, ... ] )
新增view_option_name
security_invoker ( boolean ) 取值为true或者false. 大小写不敏感,取其他值时应报错。
当取值为true时,视图访问基表和底层视图检查权限时使用视图访问者的身份。
当取值为false时,视图访问基表和底层视图检查权限时使用视图定义者(owner)的身份。
3. MySQL模式
蓝色字体为新增
- 创建视图
CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] [ RECURSIVE ] [ FORCE ] [SQL SECURITY {DEFINER | INVOKER}] VIEW name [ ( column_name [, ...] ) ]
[ WITH ( view_option_name [= view_option_value] [, ... ] ) ]
AS query
[ WITH [ CASCADED | LOCAL ] CHECK OPTION | READ ONLY ]
SQL SECURITY关键字后面跟视图的权限检查方式,可取值为INVOKER、DEFINER。大小写不敏感,取其他值时应报错。如不指定则使用DEFINER作为默认值。
指定为INVOKER时,视图访问基表和底层视图检查权限时使用视图访问者的身份。
指定为DEFINER时,视图访问基表和底层视图检查权限时使用视图定义者(owner)的身份。
- 修改视图
ALTER SQL SECURITY {DEFINER | INVOKER}] VIEW name
SQL SECURITY关键字后面跟视图的权限检查方式,可取值为INVOKER、DEFINER。大小写不敏感,取其他值时应报错。如不指定则使用DEFINER作为默认值。
指定为INVOKER时,视图访问基表和底层视图检查权限时使用视图访问者的身份。
指定为DEFINER时,视图访问基表和底层视图检查权限时使用视图定义者(owner)的身份。
5. 视图使用者权限功能示例
以Oracle模式语法为例:
\c - system
create user u1 with password '123456';
create user u2 with password '123456';
创建基表:
create table f1 ( id int ,name varchar(20) , nums int);
insert into f1 values(1,'apple',1000);
insert into f1 values(1,'apple',2000);
insert into f1 values(1,'apple',4000);
insert into f1 values(2,'orange',4000);
insert into f1 values(2,'orange',5000);
insert into f1 values(3,'grape',3500);
insert into f1 values(4,'mango',4200);
insert into f1 values(4,'mango',5500);
创建检查使用者权限的视图,通过使用者和定义者分别验证视图使用者权限的功能
\c - u1
--创建一个检查使用者权限的视图
create view v_f1 bequeath current_user as select * from f1 where id<3;
\d+ v_f1
\c - u1
--u1是定义者,视图v_f1是以使用者方式检查用户权限,所以能够查询视图中的数据
select * from v_f1;
\c - system
--赋予用户u2对视图v_f1的查询权限
grant select on v_f1 to u2;
\c - u2
--未赋予用户u2对表f1的查询权限,所以视图以使用者方式检查用户u2对底层对象权限,发现无权限,所以报错
select * from v_f1;
验证视图定义者权限
\c - u1
--修改视图v_f1的权限检查方式为定义者,则将以定义者方式检查用户的权限
alter view v_f1 bequeath definer;
\c - u2
--此时用户u2查询v_f1时,视图检查的是定义者的权限,而非使用者的权限,故而查询得到数据
select * from v_f1;
6. 视图不使用权限使用者检查功能对比
\c - system
drop table f1 cascade;
create table f1 ( id int ,name varchar(20) , nums int);
insert into f1 values(1,'apple',1000);
insert into f1 values(1,'apple',2000);
insert into f1 values(1,'apple',4000);
insert into f1 values(2,'orange',4000);
insert into f1 values(2,'orange',5000);
insert into f1 values(3,'grape',3500);
insert into f1 values(4,'mango',4200);
insert into f1 values(4,'mango',5500);
\c - u1
create view v_f1 as select * from f1 where id<3;
\d+ v_f1
\c - u2
select * from v_f1;
\c - system
grant select on v_f1 to u2;
\c - u2
select * from v_f1;
\c - system
grant select on f1 to u2;
\c - u2
select * from v_f1;
7. 视图行级安全策略与视图检查使用者权限功能结合示例
以管理员创建基表及启用基表的行级安全策略
create table t1 (c1 int,c2 int);
insert into t1 values (1,1),(1,2),(1,3),(1,4);
alter table t1 enable row level security ;
以管理员基于表t1创建视图 v1t1和v2t1 bequeath current_user
create view v1t1 as select * from t1;
create view v2t1 bequeath current_user as select * from t1;
以管理员创建访问用户授予t1、v1t1、v2t1的SELECT权限。并为其配置对表t1的访问策略
create user vuser1;
grant select on t1 to vuser1;
grant select on v1t1 to vuser1;
grant select on v2t1 to vuser1;
create policy pol_t1_test ON t1 to vuser1 using ( c2<3);
以vuser1 访问t1、v1t1、v2t1。
\c - vuser1
select * from t1;
select * from v1t1;
select * from v2t1;
可见表t1和v2t1的行级策略生效,而v1t1的行级策略不生效。视图v2t1的bequeath current_user,以vuser1的用户去检查基表访问权限。
参考资料
提供该题目相关内容在产品手册中可以系统学习的位置,例如: