设置基于Column - Level 的VPD
从Oracle 10g开始,我们可以设置基于column-level的VPD,从而保护那些资料表中的重要信息列,比如password column、Price等(这个要根据具体的应用需求来定),有两种column-level的方法可以使用:
1)使用column-level VPD 保护数据不被访问
2)Display the column with NULL values
说明:1)一个查询中包含被保护的column
2)和基于row-based VPD有所不同,在column-level VPD中,所有的行均可以被访问,但是被保护列可以被隔离或采用MASK显示。
3)column-level VPD在表和视图上均可设置
实现:和row-based VPD相似,我们只需在调用dbms_rls.add_policy的时候,指定sec_relevant_cols(指定被保护列),sec_relevant_cols_opt(MASK)两个参数即可.
下面我通过一个test case来简单的介绍一下
需求说明:
对于scott.test 表中的y 字段,不允许维护帐户(user1,user2)查看或显示为NULL。
实现过程
1)创建测试表、用户,并授予相应的权限
--建表
scott@ZHANGYU>create table test(x int,y varchar2(10));
--插入数据
scott@ZHANGYU>insert into test values(1,'zhangyu');
scott@ZHANGYU>insert into test values(2,'tiger');
commit;
--授权
sys@ZHANGYU>create user user1 identified by tiger default tablespace users temporary tablespace temp;
sys@ZHANGYU>create user user2 identified by tiger default tablespace users temporary tablespace temp;
sys@ZHANGYU>grant connect,resource to user1,user2;
scott@ZHANGYU>grant all on test to public;
2)创建策略函数,并授权
sys@ZHANGYU>run
1 create or replace function test_package(d1 varchar2,d2 varchar2) return varchar2 as
2 l varchar2(100);
3 begin
4 if(sys_context('userenv','session_user')='SCOTT') then return null;
5 else l:='1=0'; return l;
6 end if;
7* end;
函数已创建。
sys@ZHANGYU>grant execute on test_package to public;
3)设置policy
sys@ZHANGYU>exec dbms_rls.add_policy('scott','test','test_policy','sys','test_package','delete,update,insert,select',sec_relevant_cols=>'y');
--在这个security policy 设置中,实际上是这样实现的,首先判断select语句是否包含被约束的列,如果包含则执行策略函数,并返回约束 1=0,否则不返回任何约束.
4)测试column-level VPD
user1@ZHANGYU>select * from scott.test;
未选定行
user1@ZHANGYU>select x from scott.test;
X
----------
1
2
SQL>
5)补充说明
一、如果要保护多列,我们只需要在sec_relevant_cols参数中指定多个列即可(用,分开),比如
sys@ZHANGYU>exec dbms_rls.drop_policy('scott','test','test_policy');
sys@ZHANGYU>exec dbms_rls.add_policy('scott','test','test_policy','sys','test_package','delete,update,insert,select',sec_relevant_cols=>'x,y');
二、如果要采用masking option,我们只需要在设置policy的时候,指定sec_relevant_cols_opt 参数为DBMS_RLS.ALL_ROWS即可,比如:
begin
sys@ZHANGYU>exec dbms_rls.add_policy('scott','test','test_policy','sys','test_package',sec_relevant_cols=>'y',SEC_RELEVANT_COLS_OPT=>dbms_rls.all_rows);
/
在这种保护模式下,被保护的列,均显示是NULL。
user1@ZHANGYU>select * from scott.test;
X Y
---------- -
1
2
从Oracle 10g开始,我们可以设置基于column-level的VPD,从而保护那些资料表中的重要信息列,比如password column、Price等(这个要根据具体的应用需求来定),有两种column-level的方法可以使用:
1)使用column-level VPD 保护数据不被访问
2)Display the column with NULL values
说明:1)一个查询中包含被保护的column
2)和基于row-based VPD有所不同,在column-level VPD中,所有的行均可以被访问,但是被保护列可以被隔离或采用MASK显示。
3)column-level VPD在表和视图上均可设置
实现:和row-based VPD相似,我们只需在调用dbms_rls.add_policy的时候,指定sec_relevant_cols(指定被保护列),sec_relevant_cols_opt(MASK)两个参数即可.
下面我通过一个test case来简单的介绍一下
需求说明:
对于scott.test 表中的y 字段,不允许维护帐户(user1,user2)查看或显示为NULL。
实现过程
1)创建测试表、用户,并授予相应的权限
--建表
scott@ZHANGYU>create table test(x int,y varchar2(10));
--插入数据
scott@ZHANGYU>insert into test values(1,'zhangyu');
scott@ZHANGYU>insert into test values(2,'tiger');
commit;
--授权
sys@ZHANGYU>create user user1 identified by tiger default tablespace users temporary tablespace temp;
sys@ZHANGYU>create user user2 identified by tiger default tablespace users temporary tablespace temp;
sys@ZHANGYU>grant connect,resource to user1,user2;
scott@ZHANGYU>grant all on test to public;
2)创建策略函数,并授权
sys@ZHANGYU>run
1 create or replace function test_package(d1 varchar2,d2 varchar2) return varchar2 as
2 l varchar2(100);
3 begin
4 if(sys_context('userenv','session_user')='SCOTT') then return null;
5 else l:='1=0'; return l;
6 end if;
7* end;
函数已创建。
sys@ZHANGYU>grant execute on test_package to public;
3)设置policy
sys@ZHANGYU>exec dbms_rls.add_policy('scott','test','test_policy','sys','test_package','delete,update,insert,select',sec_relevant_cols=>'y');
--在这个security policy 设置中,实际上是这样实现的,首先判断select语句是否包含被约束的列,如果包含则执行策略函数,并返回约束 1=0,否则不返回任何约束.
4)测试column-level VPD
user1@ZHANGYU>select * from scott.test;
未选定行
user1@ZHANGYU>select x from scott.test;
X
----------
1
2
SQL>
5)补充说明
一、如果要保护多列,我们只需要在sec_relevant_cols参数中指定多个列即可(用,分开),比如
sys@ZHANGYU>exec dbms_rls.drop_policy('scott','test','test_policy');
sys@ZHANGYU>exec dbms_rls.add_policy('scott','test','test_policy','sys','test_package','delete,update,insert,select',sec_relevant_cols=>'x,y');
二、如果要采用masking option,我们只需要在设置policy的时候,指定sec_relevant_cols_opt 参数为DBMS_RLS.ALL_ROWS即可,比如:
begin
sys@ZHANGYU>exec dbms_rls.add_policy('scott','test','test_policy','sys','test_package',sec_relevant_cols=>'y',SEC_RELEVANT_COLS_OPT=>dbms_rls.all_rows);
/
在这种保护模式下,被保护的列,均显示是NULL。
user1@ZHANGYU>select * from scott.test;
X Y
---------- -
1
2
三、masking option只支持查询操作,对DML操作无效
PS:以上内容来自网络,待验证.