oracle 的virtual private database的全新体验
===============================================
欢迎大家同我交流:小白 enhydra_boy@tom.com
欢迎转载,请保留本声明,谢谢!
================================================
在开始对oracle的virtual private database的介绍之前,笔者想就row-rule control(行记录级访问控制)的概念简单地说几句。
行记录级访问控制问题的提出和意义?
企业的应用系统都离不开数据库系统,数据库系统的权限控制是很重要的一个环节,大型数据库系统(oracle、db2、sybase、ms sqlserver)都提供完善的用户管理机制,从而可以严密地控制数据库对象(表、视图、函数、存储过程、程序包等等)的访问。但是,这往往是对象级别的。
随着商务需求地不断地提出,出现了对于行记录控制的要求:
1) 数据查询和报表输出数据需要能够进行有效地隔离,如在一个简单地销售数据统计应用中,大区经理、地区经理和销售员查询的数据就不同。
2) asp(应用服务供应商)系统出现,在系统结构上,就出现了许多企业用户的数据都会存放在同一个数据库种,但是系统需要能够有效地隔离。
为了满足这样的需求,在业务数据表需要中加上一些字段来进行控制,应用的开发往往会另行开发很多代码来实现行记录控制。但是,随着业务的变化,我们会发现开发和维护这种管理需求的成本越来越高。
我们需要寻找一种新的解决方案,能够使应用系统的架构设计简单,扩展性强,管理和维护的成本很低。
oracle8i的一个新特性virtual private database
oracle 8i提供了一个新的特性,来实现行级规则的控制,称之为virtual private database。充分利用8i提供的virtual private database技术,可以实现,一个数据库schema的数据同时给多个数据库用户访问,但是又能很好地隔离各自的数据内容。显然,这已经不是原来的对象级的控制的概念。
下面是笔者的体验,写下来,供大家参考。我先通过一个简单的例子,来说明oracle 8i的这个新特性(需oracle 8i的企业版才支持)。
环境:windows 2000 server + oracle 8.1.7(enterprise edition)
在scott用户下,有一个customers表,记录着客户资料,以后为每个客户分配一个oracle数据库登陆账号,客户可以登陆,查询自己的订单情况。那么,我们需要做的就是能够把每个登陆账号和客户代码对应起来。就是说要实现一个映射关系,当然,通过自己建关系映射表,写代码做,也可以实现,但是oracle 8i把这一切变地非常简单(我接下来的介绍都会围绕着oracle 8i这项技术是我们的工作如何更加简单,如何更加容易控制,请记住,这是笔者写这篇文章的目的)。
--建立一个secusr的账号,用于权限控制用
connect system/manager@oracle;
create user secusr identified by secusr;
grant connect,resource,dba to secusr;
--把customers的查询权利赋予secusr
connect scott/tiger@oracle;
grant select on "customers" to secusr;
--连接到secusr用户
connect secusr/secusr@oracle;
--创建上下文
create context customer_context using secusr.customer_security_context;
--创建程序包customer_security_context
create or replace package
secusr.customer_security_context is
procedure set_customerid;
end;
create or replace package body
secusr.customer_security_context is
procedure set_customerid is
begin
if sys_context('userenv','session_user')='scott' then
dbms_session.set_context('customer_context','customerid','alfki');
end if;
end;
end;
--授权
grant execute on secusr.customer_security_context to public;
oracle 8i中提供了context(连接上下文)的概念,类似于asp中的session,你可以为当前这个连接设置多个全局变量,记录信息,这个信息一直保持到连接被释放。上面的代码,就是为用scott账号登陆的连接,进行了一次客户代码的映射(scott->alfki),而且,随时可以sys_context来查询。
具体代码如下:
sql> connect scott/tiger@oracle;
已连接。
sql> execute secusr.customer_security_context.set_customerid;
pl/sql 过程已成功完成。
sql> select sys_context('customer_context','customerid') from dual;
sys_context('customer_context','customerid')
--------------------------------------------------------------------------------
alfki
但是,我觉的还不够,能够做到每个连接建立的时候,就自动完成这种映射,令人高兴的是,oracle 8i提供了系统级的触发器,让我轻松地实现。
--scott用户登陆触发器
connect system/manager@oracle
create or replace trigger scott.tg_set_usr_context
after logon on database
begin
secusr.customer_security_context.set_customerid;
end;
--断掉connection,重新登陆
oracle8i enterprise edition release 8.1.7.0.0 - production
with the partitioning option
jserver release 8.1.7.0.0 - production
sql> connect scott/tiger@oracle
已连接。
sql> select sys_context('customer_context','customerid') from dual;
sys_context('customer_context','customerid')
--------------------------------------------------------------------------------
alfki
sql>
好了,够简单吧。
采用virtual private database如何达到sql dml上的数据控制访问要求呢?
virtual private database技术可以对一张表的记录设置dml操作的过滤策略。oracle8i提供了policy的概念,并且为此配备了一套系统程序包,来完成设置。下面,我来介绍一下:
connect secusr/secusr@oracle
--做一个函数,返回对应的过滤条件
create or replace package secusr.customer_security is
function customer_sec
return varchar2;
end;
create or replace package body secusr.customer_security
is
function customer_sec(d1 varchar2,d2 varchar2)
return varchar2
is
begin
if sys_context('userenv','session_user') in ('sys','system','secusr') then
return null;
else
return 'customerid=''' sys_context('customer_context','customerid') '''';
end if;
end;
end;
--设置表数据的分割过滤
execute dbms_rls.add_policy('scott','"customers"','customers_sec_policy',
'secusr',
'customer_security.customer_sec',
'select,update,delete');
customer_security程序包的customer_sec函数实现了,根据但前的context中customerid的内容,来返回一个过滤的策略,函数的参数形式是固定的。通过dbms_rls程序包的add_policy过程,把策略条件同表绑定以来,以后,每次select,update,delete都会自动应用这个策略。
好了,现在我们来测试一下
--用scott登陆,只能看到自己的信息
sql> connect scott/tiger@oracle;
已连接。
sql> select customerid,city from "customers";
customerid city
---------- ------------------------------
alfki berlin
--用system登陆,可以看到所有的
sql> connect system/manager@oracle;
已连接。
sql> select customerid,city from "scott"."customers";
customerid city
---------- ------------------------------
alfki berlin
anatr méxico d.f.
anton méxico d.f.
arout london
bergs lule? d.f.
blaus mannheim
blonp strasbourg
bolid madrid
bonap marseille
bottm tsawassen
bsbev london
非常好,完全满足了要求,现在可以放心地把scott账号给客户(alfki)了,客户可以查询自己的订单情况,当然只能是自己的。
sql> select a.orderid,a.customerid,a.orderdate,
2 sum(c.unitprice*c.quantity*(1-c.discount)) as totalmoney
3 from "orders" a,"customers" b ,"order details" c
4 where a.customerid=b.customerid and a.orderid=c.orderid
5 group by a.orderid,a.customerid,a.orderdate;
orderid customerid orderdate totalmoney
---------- ---------- ---------- ----------------------------------------
10643 alfki 25-8月 -97 814.5
10692 alfki 03-10月-97 878
10702 alfki 13-10月-97 330
10835 alfki 15-1月 -98 845.8
10952 alfki 16-3月 -98 471.2
11011 alfki 09-4月 -98 933.5
已选择6行。
下面,让我总结一下virtual private database的优点:
l 提供了一种可行的、可靠的、对用户完全透明的行规则控制方案
同自己建立一套用户控制权限不同,virtual private database对用户是透明的,你的应用程序不用去考虑这点,你的应用程序需要的是更加集中于你的业务处理过程的实现,而不要让数据隔离控制,成为你业务处理的一个过程。你可以完全先开发功能应用,然后再加上数据隔离的控制,而这种控制,是基于后台数据库系统的,这种变动与现有的应用程序完全兼容,不会引起现有的程序不能运行
l 控制更加严密,不仅对于业务系统才有效
由于采取的是后台数据库技术,所以这种控制,对所有的应用(除了业务系统,数据库管理工具等等)都起到了控制作用。相比之下,采用自己的权限控制的应用中,只能做到在业务系统的应用中有效,而其他(sqlplus,sqlplus worksheet等等)就完全没有效果。而且大多系统都采用使用一个数据库账号登陆到系统的方案,在这种情况下,这个账号对于业务数据库一般来说操作权限很高,而这个账号一旦泄漏,攻击者利用sqlplus工具可以方遍地窃取数据。
l 和用应用程序自己实现的方法相比,这种技术更加灵活,而且便于管理,同时开发成本也是最低的。
采用了这种行记录控制技术,不需要通过应用程序实现,大大地简化了应用系统地复杂性,同时也让你的系统的结构很清晰,而出现错误的可能性就更低了。当然,你自己建立的控制系统也可以做到oracle 8i的功能,但是会大大加大开发成本。
l 对于asp(应用服务供应商)系统,满足了用户数据存放在一起,但又能够独立分开访问的要求。笔者觉得,这项技术,对于构建asp应用系统的用户特别有用,充分利用oracle提供的新技术,让你的系统更加安全、可靠。
总之,virtual private database是一个功能强大的行级规则控制技术,是oracle8i提供给我们的一个强有力的特性,充分地应用,可以大大节省软件开发成本。
笔者认为virtual private database技术是一个非常有用的技术,而在sql server 2000和sybase ase 12.5中,没有看到类似的技术。
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器