资源描述
文件:开发指引 创建日期:2016-07-05
版本: 1.0 更新日期:2016-07-07
VPD学习总结
作 者: tudengfeng
创建日期: 2016-7-5
更新日期: 2016-7-7
版 本: 2.0
文档控制
修改记录
修改日期
作者
版本
更改说明
2016-7-5
tudengfeng
1.0
原始文档
2016-7-7
Tudengfeng
2.0
补充
复核记录
日期
复核人
版本
复核说明
审批记录
审批日期
审批人签字
审批人角色
版本
目 录
文档控制 ii
1. 前言 1
1.1. 背景 1
1.2. 适用范围 1
1.3. 参考文档 1
1.4. 简称、缩略词、术语和定义 1
1.5. 图例说明 1
2. VPD 3
2.1. 基础内容 3
3.1. VPD 策略实现过程 3
3. 遗留和已结问题 11
5.1. 遗留问题 11
5.2. 已结问题 11
11 /14
1. 前言
1.1. 背景
指引开发人员了解VPD策略的实现与详细控制
1.2. 适用范围
1.3. 参考文档
无
1.4. 简称、缩略词、术语和定义
缩略词术语
定义
1.5. 图例说明
图例
说明
图例
说明
开始
判断
引用其他子 流程
部门或岗位名称
动态流程连接线
注释框
“否”连接线
从系统内打印的单据
“是”连接线
ERP系统外打印的单据
ERP系统外流程
结束
系统内流程
GxP受控点
文件:VPD学习总结 创建日期:2016-07-05
版本: 2.0 更新日期:2016-07-07
2. VPD
2.
2.1. 基础内容
以下内容来源于网络(百度,贴吧,论坛等)
VPD(虚拟专用数据库)提供了角色和视图无法提供的行级访问控制。
即安全性控制。在EBS二次开发中,涉及到多组织访问权限控制(MOAC),对于同一张表的查询控制,不同的访问权限最终所查询出来的结果是不相同的。VPD便是实现MOAC的常用技术。
一个应用场景:
某集团公司下边主要分为三个区域(北美,欧洲,亚太),亚太区你是一采购部经理,负责所有七个Operation Unit。
这 种情况下,系统管理员可以创建一个security profile,这个security profile设置成可以访问这七个亚太组织,并把这个security profile赋予到你的responsibility下,这样你就能在同一个职责下访问这七个OU了,就不用不停地切换职责来访问不同OU了。
另外如果你要经常处理中国OU下的事务,那么你可以设置Profile:MO: Default Operating Unit到中国,那么业务默认的OU就是中国了。
vpd的作用比较广泛,不仅仅是用于数据屏蔽,还用于安全方面他屏蔽粒度大到整个表,小到某一列,这些都是可控的。
3.
3.1. VPD 策略实现过程
创建表和视图
DROP TABLE hand_vpd_test_tb1;
create table hand_vpd_test_tb1
(name_col varchar2(30),
sex varchar2(30),
id_num number
)
create or replace view hand_vpd_test_v as
select * from hand_vpd_test_tb1
where mod(id_num,2) = 0;
插入数据
BEGIN
FOR i IN 1..10 LOOP
INSERT INTO hand_vpd_test_tb1(name_col,sex,id_num) VALUES('TEST'||I,i||'男',i);
END LOOP;
END;
对整张表执行查询:
SELECT * FROM hand_vpd_test_tb1;
对视图执行查询:
select * from hand_vpd_test_v;
调用API将策略加入对象:
API:dbms_rls.add_policy();
-- ------------------------------------------------------------------------
-- add_policy - add a row level security policy to a table or view
--
-- INPUT PARAMETERS
-- object_schema - schema owning the table/view, current user if NULL
-- object_name - name of table or view
-- policy_name - name of policy to be added
-- function_schema - schema of the policy function, current user if NULL
-- policy_function - function to generate predicates for this policy
-- statement_types - statement type that the policy apply, default is any
-- update_check - policy checked against updated or inserted value?
-- enable - policy is enabled?
-- static_policy - policy is static (predicate is always the same)?
-- policy_type - policy type - overwrite static_policy if non-null
-- long_predicate - max predicate length 4000 bytes (default) or 32K
-- sec_relevant_cols - list of security relevant columns
-- sec_relevant_cols_opt - security relevant column option
PROCEDURE add_policy(object_schema IN VARCHAR2 := NULL, -- 对象所有者 可为空
object_name IN VARCHAR2, -- 对象名称
policy_name IN VARCHAR2, -- 策略名称
function_schema IN VARCHAR2 := NULL,--函数有所着 即包名 可为空,当置为空时函数独立存在数据库中。不属于包。
policy_function IN VARCHAR2, --函数名
statement_types IN VARCHAR2 := NULL,--策略被应用的语句 默认为任何(增删改查),也可指定相应的模式(语句为’select ,delete,update,insert’)
update_check IN BOOLEAN := FALSE,-- 更新检查 在执行插入或是更新操作时,需要判断更新操作标识,只对满足该条件的数据更新
enable IN BOOLEAN := TRUE,
static_policy IN BOOLEAN := FALSE,
policy_type IN BINARY_INTEGER := NULL,
long_predicate BOOLEAN := FALSE,
sec_relevant_cols IN VARCHAR2 := NULL, --将屏蔽粒度限制到具体某一列
sec_relevant_cols_opt IN BINARY_INTEGER := NULL); --当屏蔽粒度为列时,对于其他列是否全显示
sec_relevant_cols和sec_relevant_cols_opt两个参数一般是同时存在的,意义在于控制具体一列的数据。
将非sex列的所有数据显示出来,sex列用空格填充,参数为:
sec_relevant_cols => 'sex',
sec_relevant_cols_opt => dbms_rls.all_rows
控制条件为:id_num = 3 其应用结果为:
若只存在将粒度设置为列,且不以空填充其他行,参数为:
sec_relevant_cols => 'sex',
sec_relevant_cols_opt => NULL
控制条件为id_num=3,其运行效果为:
若不存在这两个条件,同样的控制条件下,其运行效果为:
以上两种控制的区别在于粒度大小,以及其他行的显示情况;
对于策略更新检测,若违反了安全策略将会报错,这里的控制为id_num = 3,进行插入操作时产生效果为:
添加策略
1. 表:
BEGIN
dbms_rls.add_policy(object_schema => 'apps',
object_name => 'hand_vpd_test_tb1',
policy_name => 'HAND_TEST_P',
function_schema => 'apps',
policy_function => 'cux_hand_vpd_test_pkg.vpd_select',
update_check => TRUE,
statement_types => 'select',
sec_relevant_cols => 'sex',
sec_relevant_cols_opt => NULL
);
END;
为表名为hand_vpd_test_tb1添加策略,策略名为HAND_TEST_P,策略函数是cux_hand_vpd_test_pkg.vpd_select,且该策略只在查询是被执行。屏蔽粒度为列,被控制的列是sex,并不显示非控制列的其他列。
Function vpd_select() 内容为:
FUNCTION vpd_select(p_owner IN VARCHAR2, p_obj IN VARCHAR2) RETURN VARCHAR2 IS
l_ret VARCHAR2(2000);
BEGIN
l_ret := 'mod(id_num,2) != 0';
RETURN l_ret;
END vpd_select;
PS. 策略函数必须包含object_schema和object_name两个参数。 在调用时,将会把all_policies表中该条记录中,列为object_owner和object_name值传入。即使在安全策略函数中不使用也要带上个参数,否则在执行时会出现“ORA-28112: 无法执行策略函数”的错误提示。
执行SELECT * FROM hand_vpd_test_tb1;,运行结果为:
在这里向表hand_vpd_test_tb1插入或更新数据不受策略控制。
使用相同的策略函数,但受控制的列为sex,id_num,并全显示非控制列:
BEGIN
xc_test_pkg.log('this begin');
dbms_rls.add_policy(object_schema => 'apps',
object_name => 'hand_vpd_test_tb1',
policy_name => 'HAND_TEST_P',
function_schema => 'apps',
policy_function => 'cux_hand_vpd_test_pkg.vpd_select',
update_check => TRUE,
statement_types => 'select',
sec_relevant_cols => 'sex,id_num', --可随意控制相应列
sec_relevant_cols_opt => dbms_rls.ALL_ROWS --非控制列全显示
);
END;
其运行效果如下:
视图与表
策略对象可以是视图也可以是表/同义词。
同样,使用API将策略添加到对象(hand_vpd_test_v):
BEGIN
dbms_rls.add_policy(object_schema => 'apps',
object_name => 'hand_vpd_test_v',
policy_name => 'HAND_TEST_P_V',
function_schema => 'apps',
policy_function => 'cux_hand_vpd_test_pkg.vpd_select_v',
statement_types => 'select',
sec_relevant_cols => 'sex',
sec_relevant_cols_opt => dbms_rls.all_rows);
END;
策略函数cux_hand_vpd_test_pkg.vpd_select_v()的内容为:
FUNCTION vpd_select_v (p_owner IN VARCHAR2, p_obj IN VARCHAR2) RETURN VARCHAR2 IS
l_ret VARCHAR2(2000);
BEGIN
l_ret := 'id_num != 4';
RETURN l_ret;
END vpd_select_v;
其运行结果为:
从实验结果来看,对表的控制将会影响到对视图的控制。对视图的控制不会影响到表的控制;ps.前提是视图是基于这张表建立的。
插入、更新与删除
策略函数不仅对查询操作有控制,对其他的DML同样可以起到限制作用。
在上述的策略函数作用下,执行delete from hand_vpd_test_v 然后整张表的数据并没有被全部删除 只是删除了满足策略函数中的条件的数据。最后其运行效果为:
注: TEST11这条记录与之前有出入是因为手动插入了这条数据。
当插入或更新一条不满足策略函数条件的数据时,会报错。
BEGIN
xc_test_pkg.log('this begin');
dbms_rls.add_policy(object_schema => 'apps',
object_name => 'hand_vpd_test_tb1',
policy_name => 'HAND_TEST_P',
function_schema => 'apps',
policy_function => 'cux_hand_vpd_test_pkg.vpd_select',
update_check => TRUE
);
END;
执行insert into hand_vpd_test_tb1(NAME_COL,SEX,ID_NUM) values ('TEST12','12男','12');由于违反策略函数,报错:
注:必须将update_check标识符设置为true。
3. 遗留和已结问题
4.
5.
5.1. 遗留问题
序号
说明
影响程度
负责人
计划日期
1
2
3
4
5
5.2. 已结问题
序号
说明
影响程度
负责人
计划日期
展开阅读全文