资源描述:
《VPD在DCS系统上的设想(未采用)》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、业务背景:DCS与OCS系统要进行合并。App(完全相同)与数据库(双库有共同的表结构)要合并到一起。要求DCS与OCS要灵活对自己或对方数据进行访问与DML操作。初步的解决方案:·原来两个DB用户保留,自己的表亦分开存在在各种用户下。缺点:APP中加入对表的OWNER的标识,改动量大。·以DCS用户的表为基础,OCS的数据插入到DCS的表中,表中加入DATA_OWNER列标识每行数据的来源。缺点:APP中的WHERE条件中加入对DATA_OWNER的过滤,但无法阻止对方相互访问与修改对方的数据,安全性差。两个方案的缺点:无论哪种方案,都将面临
2、APP的大量修改,且有双方数据互相被误修改的风险。替代方案,使用OracleVPD。VPD即VirtualPrivateDatabases,虚拟专用数据库。ORACLE允许通过这项技术控制数据库对象行级访问。可使用VPD技术,限制应用程序的每个用户只能看到表的某个部分数据(即不同APP所属数据库之间的数据隔离)。这种行级安全是通过附加一个安全策略到数据库对象(如表,视图或同义词)实现。不管用户使用什么工具访问数据库,用户都不能避开这种行级安全措施,除非在策略失效的情况下,才会访问到该数据库对象的全部数据。由于数据库实施VPD后它提供了比基于应用
3、更强的安全性。VPD使用某种查询重写来限制用户访问表和视图的行。安全策略附加到希望控制访问的表,并且编写存储过程来修改针对这些表所构造的SQL语句。例如当用户发布针对带这种安全策略的表的一条UPDATE语句时,ORACLE将动态附加一个谓词(一条WHERE子句)到用户语句以修改它,并限制用户对此表访问。VPD的实现原理其实与应用程序编程实现类似,只是采用数据库底层实现,主要步骤和原理如下:·在用户登录或执行查询时设置应用程序上下文(context),与在SQL语句中进行限制类似,ORACLE在这里采用context的方式来记录用户(对于管控系统
4、来说就是会计主体)的信息。·根据要求编写WHERE条件组织函数(过滤条件):用户数据是如何被限制的呢?其实在用户执行SQL语句时,ORACLE自动在末尾加上了以上下文中ID为特征的限制条件。用户可以编写函数实现,在函数中灵活控制各个用户的数据可见性。·应用VPD:通过第一二步,对于应用了策略的表,不同的用户均只能访问各自的数据了。·对于DML语句,在策略有效的情况下,VPD策略将自动过滤数据,但对于TRUNCATE(DDL)语句,策略对于DLL语句将失效,仍然会把数据表全部数据删除。以上讲的是查询例子,事实上,删除及修改与查询完全类似,对于数据
5、插入,稍有不同,由于应用程序并不知道策略所用到的字段,因此,在创建表时,必须对策略使用的字段赋默认值(default),这个默认值就是上下文(context)对应的值。这样,就成功的解决了不同用户对数据访问权限的问题。本次DCS与OCS的合并,部分需要增加策略的表同时增加了一个字段:DATA_OWNER,这个字段用于保存数据所归属的APP代号。对于这些使用VPD技术的表均使用了策略(policy),同时均建立同义词,这样,在登录到单位库时,可以像以前一样访问属于当前单位的数据,完全无需作任何修改。举例说明:用户HOCS_WONER,HDMP_C
6、S_ADMIN都拥有相同表结构的表ABC,ABC中的数据分别如下:HOCS_WONER.ABCHDMP_CS_ADMIN.ABCIDNAMEIDNAME1AAA1DDD2BBB4EEE3CCC5FFF将来业务需要合并到一起,而且后面加入一个DH列,以标识此数据来源自原来的哪个用户:IDNAMEDATA_OWNER1AAADCS2BBBDCS3CCCDCS1DDDNVO4EEENVO5FFFNVO测试用数据:CREATETABLEABC(IDNUMBER(5),NAMEVARCHAR2(30),DATA_OWNERVARCHAR2(3));INS
7、ERTINTOABC(ID,NAME,DATA_OWNER)VALUES(1,'SSSSSS','DCS');INSERTINTOABC(ID,NAME,DATA_OWNER)VALUES(2,'BBB','DCS');INSERTINTOABC(ID,NAME,DATA_OWNER)VALUES(3,'CCC','DCS');INSERTINTOABC(ID,NAME,DATA_OWNER)VALUES(1,'DDD','NVO');INSERTINTOABC(ID,NAME,DATA_OWNER)VALUES(4,'EEE','NVO');
8、INSERTINTOABC(ID,NAME,DATA_OWNER)VALUES(5,'FFF','NVO');COMMIT;目的效果:每个非owner