第一步 创建政策函数
无论AM何时要查看客户的账户信息,他都必须动态地应用银行的访问规则(包含在ACCESS_POLICY表中)。第一步是创建政策函数,用于返回要应用到表上的适当判定词。和对ACCESS_POLICY表的处理一样,出于安全考虑,政策函数也由用户的SECMAN创建和控制。最好是使隐私规则与它们将要应用到的表分开。
让我们仔细看一看政策函数get_sel_cust_id:
准确接收两个参数:模式名称(p_schema in varchar2)和表名(p_table in varchar2)。
只返回一个字符串值--return varchar2 as l_retstr varchar2(2000),它包含将要添加到表的每个查询中的判定词。
使用一个游标例程--for cust_ rec in--来获得值的列表,因为每个用户可能有表中列出的几个cust_id。
返回一个结构化的字符串l_retstr,无论用户何时试图访问基本表都将它用做一个判定词。
该函数返回判定词where cust_id in,随后是用户(am_name = USER)能够看到的客户账户名单(由逗号分隔)。
请注意在进入构建用户cust_id名单的循环之前,先检查该用户是否为表的所有者BANK,若是则返回NULL,如下所示:
if (p_schema = user) then
1_retstr := null;
构建完该函数后,你需要通过测试一些示例数据来确保它返回相应的判定词。以SECMAN身份连接数据库,向ACCESS_POLICY表中插入一些记录,授予SECMAN在几个示例账户上的读权限,如下所示:
insert into access_policy values ('SECMAN',123,'S');
insert into access_policy values ('SECMAN',456,'S');
insert into access_policy values ('SECMAN',789,'S');
下面来执行该函数:
select get_sel_cust_id
('BANK','CUSTOMERS') from dual;
该函数返回一个将被用作判定词的字符串,如下面的示例输出所示:
GET_SEL_CUST_ID('BANK','CUSTOMERS')
------------------------
CUST_ID IN (123,456,789)
你需要为其他类型的访问创建类似的函数。为简单起见,为所有其他访问类型创建一个单一的函数--UPDATE, DELETE, INSERT。但是注意,对于现实世界中的应用,每种访问类型应该有自己的单独定义的函数,以确保相应的隐私。
政策函数基本上是一样的,唯一的区别是通过使用ACCESS_CONTROL表中的信息进一步限定了判定词:
and access_type in ('I', 'U', 'D')
创建政策函数仅仅是第一步。现在你需要通过定义在你的系统中控制该函数的使用政策来确保这个函数将被使用。
第二步 定义政策
政策是用Oracle提供的DBMS_RLS包定义的。要知道政策本身并不是任何用户(schema)拥有的数据库对象,它们是逻辑结构。拥有对DBMS_RLS包的执行权限的用户可以修改或删除由其他用户创建的政策。对DBMS_RLS的执行权限应该受到严谨的控制。
在下面的例子中,用户SECMAN被(SYS)授予对DBMS_RLS包的执行权限:
grant execute on dbms_rls to secman;
创建了一个关于模式BANK的CUSTOMERS表的政策,命名为CUST_SEL_POLIC。该政策将模式SECMAN拥有的函数GET_SEL_CUST_ID所返回的判定词应用到对该表的所有SELECT操作语句。
同样,对其他访问类型该表应遵循不同的政策。该政策应用于对CUSTOMERS表的INSERT、UPDATE和DELETE操作语句。
该政策与SELECT政策几乎一样,但它包含如下一项检查以确保即使执行完UPDATE该政策仍然得到遵循:
update_check => TRUE
除非遵守该政策,否则数据不能被添加到该表中。