演示一个VPD进行数据访问控制的示例

更多精彩内容尽在www.leonarding.com


1.什么是VPDVirtual PrivateDatabase 虚拟私有数据库,听起来像是一个独立自主的数据库,其实在逻辑上是独立的,物理上就是一个数据库。原理就是通过指定过滤策略,对用户的SQL添加谓词条件,来达到过滤数据的目的。

2.VPD优点:

精细化访问

对业务透明,不同的客户发出相同SQL语句,查询到的结果集不一样,可以让不同客户只看其相关的数据

对用户透明,用户感知不到

不对数据本身做任何操作,只在SQL层面进行过滤处理

VPD是数据库默认自带的,无需独立安装

3.实验

我们建一张业务表car,有汽车名,汽车数量,汽车价格三个字段,插入9条记录,分成高中低三个档次

LEO1@LEO1>create table car (namevarchar2(20),num number,cost number);

Table created.

LEO1@LEO1>insert into carvalues('toyota',10,30);         高级车

1 row created.

LEO1@LEO1>insert into carvalues('volvo',50,30);

1 row created.

LEO1@LEO1>insert into carvalues('honda',60,30);

1 row created.

LEO1@LEO1>insert into carvalues('biaozhi',70,20);        中级车

1 row created.

LEO1@LEO1>insert into carvalues('xuetielong',80,20);

1 row created.

LEO1@LEO1>insert into car values('polo',90,20);

1 row created.

LEO1@LEO1>insert into carvalues('xiali',20,10);          低级车

1 row created.

LEO1@LEO1>insert into carvalues('jili',30,10);

1 row created.

LEO1@LEO1>insert into carvalues('byd',40,10);

1 row created.

LEO1@LEO1>commit;

Commit complete.

LEO1@LEO1>select * from car;

NAME                        NUM       COST

-------------------- ------------------------------ -------------------- ----------

toyota                       10         30

volvo                        50         30

honda                       60         30

biaozhi                      70         20

xuetielong                   80         20

polo                         90        20

xiali                         20        10

jili                          30        10

byd                         40         10

9 rows selected.

我们的思路:car表上添加过滤策略“filter_name”和“filter_num”,当select语句中有name字段时触发“filter_name”策略,当select语句中有num字段时触发“filter_num”策略,过滤策略由函数“fun_name”和“fun_num”实现。

创建函数“fun_name

LEO1@LEO1>create or replace functionfun_name (fun_scheme varchar2,fun_object  varchar2)

return varchar2 as fun_cost varchar2(20);

begin

fun_cost:='cost=30';

return(fun_cost);

end fun_name;

/

2    3    4   5    6    7  

Function created.

创建函数“fun_num

LEO1@LEO1>create or replace functionfun_num (fun_scheme varchar2,fun_object varchar2)

return varchar2 as fun_cost varchar2(20);

begin

fun_cost:='cost=10';

return(fun_cost);

end fun_num;

/

2    3    4   5    6    7  

Function created.

添加过滤策略“filter_name

LEO1@LEO1>begin

dbms_rls.add_policy(

object_schema => 'leo1',

object_name => 'car',

policy_name => 'filter_name',

policy_function => 'fun_name',

sec_relevant_cols => 'name');

end;

/

2    3    4   5    6    7   8    9  

PL/SQL procedure successfully completed.

添加过滤策略“filter_num

LEO1@LEO1>begin

dbms_rls.add_policy(

object_schema => 'leo1',

object_name => 'car',

policy_name => 'filter_num',

policy_function => 'fun_num',

sec_relevant_cols => 'num');

end;

/

2    3    4   5    6    7   8    9  

PL/SQL procedure successfully completed.

当我们要查询汽车名的时候,会触发filter_name过滤策略,从而调用fun_name函数限制where cost=30的记录显示

LEO1@LEO1>select name,cost from car;

NAME                       COST

-------------------- ----------

toyota                       30

volvo                        30

honda                       30

当我们要查询汽车数量的时候,会触发filter_num过滤策略,从而调用fun_num函数限制where cost=10的记录显示

LEO1@LEO1>select num,cost from car;

      NUM       COST

---------- ----------

       20         10

       30         10

       40         10

当我们不想使用过滤策略的时候,如何删除?

使用drop_policy存储过程来删除,filter_namefilter_num过滤策略

LEO1@LEO1>execute dbms_rls.drop_policy('leo1','car','filter_name');

PL/SQL procedure successfully completed.

LEO1@LEO1>execute dbms_rls.drop_policy('leo1','car','filter_num');

PL/SQL procedure successfully completed.

LEO1@LEO1>select * from car;

NAME                        NUM       COST

-------------------- ---------- ----------

toyota                       10         30

volvo                        50         30

honda                        60         30

biaozhi                      70         20

xuetielong                   80         20

polo                         90         20

xiali                        20         10

jili                         30         10

byd                         40         10

9 rows selected.

利用VPD隐藏敏感列信息

我们设计一个新的“filter_num”策略,只显示cost=10的记录,隐藏num列的汽车数量

LEO1@LEO1>begin

dbms_rls.add_policy(

object_schema => 'leo1',

object_name => 'car',

policy_name => 'filter_num',

policy_function => 'fun_num',

sec_relevant_cols => 'num',

sec_relevant_cols_opt =>dbms_rls.all_rows);      只显示相关的行信息

end;

/

2    3    4   5    6    7   8    9   10  

PL/SQL procedure successfully completed.

LEO1@LEO1>select * from car;

NAME                        NUM       COST

-------------------- ---------- ----------

toyota                                   30

volvo                                    30

honda                                   30

biaozhi                                  20

xuetielong                               20

polo                                    20

xiali                         20        10

jili                          30         10

byd                        40         10

9 rows selected.

小结:VPD是一种行级安全控制,操作简单无需添加任何组件即可实施。



Leonarding
2013.6.14
北京
&summer
分享技术~
成就梦想
Blogwww.leonarding.com

 

你可能感兴趣的:(数据库,insert,VPD,透明加密,虚拟私有数据库)