VPD :Virtual Private Database , 是一种限制对数据库信息细粒度的访问控制技术。实现的关键在于:RLS(Row Level Security) 行级权限控制,通过 ORACLE 的 存储过程:dbms_rls.add_policy 实现.
实现原理:
查询时在 WHERE 语句后 加上 'AND ...', 该功能由策略函数实现。
下面用PL/SQL 简单举例演示。
--创建测试表
CREATE TABLE T(organization_id NUMBER,organization_code VARCHAR2(3), organization_name VARCHAR2(150));
--插入测试数据
INSERT INTO T VALUES (101,'AAA','name1');INSERT INTO T VALUES (102,'BBB','name2');INSERT INTO T VALUES (103,'CCC','name3');INSERT INTO T VALUES (104,'DDD','name4');
--查询所有数据
SELECT * FROM T;
实现如下访问控制:
拒绝访问 organization_id = 101 的行.
--step 1: 创建查询策略函数
CREATE OR REPLACE FUNCTION f_limited_query_t (s_schema IN VARCHAR2,
s_objectIN VARCHAR2) RETURN VARCHAR2
AS
BEGIN
RETURN 'organization_id not in(101)';END;
-- PS:该函数必须有两个 VARCHAR2 参数,不能去掉,否则报错:ORA-28112: failed to execute policy function
--step 2: 为对象添加查询策略
BEGINDBMS_RLS.add_policy (object_schema=> 'APPS',object_name => 'T',
policy_name=> 'POLICY_LIMITED_QUERY_T',
function_schema=> 'APPS',
policy_function=> 'F_LIMITED_QUERY_T'); -- 可以使 package.functionEND;
--step 3: 测试
SELECT * FROM T;
--结果:不能访问到 organization_id = 101 的行. 说明访问策略生效
--step 4:解除访问控制
BEGINDBMS_RLS.drop_policy (object_schema=> 'APPS',object_name => 'T',
policy_name=> 'POLICY_LIMITED_QUERY_T');END;
-------------------我是分割线--------------------------
add_policy 部分字段解释:
dbms_rls.add_policy(object_schema --object schema
,object_name --object name
,policy_name --policy 名, 自己命名
,function_schema --function schema
,policy_function --策略函数
,statement_types --要使用该 policy 的 DML 类型,如'select,insert,update,delete'
,update_check --仅适用于statement_type为'insert,update',值为'true'或'false'
,enable --是否启用,值为'true'或'false'
);
--设置 policy
dbms_rls.enable_policy(object_schema --object schema
,object_name --object name
,policy_name --要删除的policy名称
,enable --是否启用,值为'true'或'false'
);
--通过 VPD 进行 OU 屏蔽
BEGINdbms_rls.add_policy(object_name => 'CIB_TABLE',
policy_name=> 'ORG_SEC',
policy_function=> 'MO_GLOBAL.ORG_SECURITY',
policy_type=>dbms_rls.shared_context_sensitive);END;
--查看系统中的 policy
SELECT * FROM user_policies
使用案例:
为不带ALL的APPS下的同义词添加策略函数:BEGINdbms_rls.drop_policy(object_schema=> 'APPS',object_name => 'CUX_CM_COMMISSION_DTLS',
policy_name=> 'ORG_SEC');END;BEGINdbms_rls.add_policy(object_name => 'CUX_CM_COMMISSION_DTLS',
policy_name=> 'ORG_SEC',
policy_function=> 'MO_GLOBAL.ORG_SECURITY');END;