本文档风哥主要介绍Oracle PDB虚拟私有数据库(Virtual Private Database,VPD)相关知识,包括PDB虚拟私有数据库的概念、PDB虚拟私有数据库的组件、PDB虚拟私有数据库的配置、PDB虚拟私有数据库策略创建、PDB虚拟私有数据库验证、PDB虚拟私有数据库故障处理等内容,由风哥教程参考Oracle官方文档Security内容编写,适合DBA人员在学习和测试中使用,如果要应用于生产环境则需要自行确认。
Part01-基础概念与理论知识
1.1 PDB虚拟私有数据库的概念
Oracle PDB虚拟私有数据库(Virtual Private Database,VPD)是一种行级别安全控制技术,用于在查询时动态过滤数据。VPD通过在表或视图上应用安全策略,实现基于用户、角色或其他上下文信息的行级别访问控制。VPD适用于需要行级别数据隔离的企业环境。更多视频教程www.fgedu.net.cn
- 行级别访问控制
- 动态过滤数据
- 基于上下文信息
- 对应用程序透明
- 支持多种策略类型
1.2 PDB虚拟私有数据库的组件
Oracle PDB虚拟私有数据库的组件包括:
- 策略函数(Policy Function):定义访问控制逻辑
- 策略(Policy):将策略函数应用到表或视图
- 上下文(Context):存储访问控制上下文信息
- 策略组(Policy Group):管理多个策略
- 策略类型(Policy Type):定义策略执行时机
1.3 PDB虚拟私有数据库的优势
Oracle PDB虚拟私有数据库的优势:
- 数据保护:保护敏感数据的安全性
- 行级别安全:实现行级别访问控制
- 透明性:对应用程序透明
- 灵活性:支持灵活的访问控制
- 集中管理:集中管理访问控制策略
Part02-生产环境规划与建议
2.1 PDB虚拟私有数据库规划
Oracle PDB虚拟私有数据库规划要点:
– 敏感数据识别:识别需要保护的敏感数据
– 策略函数规划:定义访问控制逻辑
– 策略规划:将策略函数应用到表或视图
– 上下文规划:存储访问控制上下文信息
# 策略函数规划
– 函数名称:定义策略函数名称
– 函数参数:定义函数参数
– 函数逻辑:定义访问控制逻辑
– 函数返回值:定义返回的谓词
# 策略规划
– 策略名称:定义策略名称
– 策略对象:定义策略应用的对象
– 策略类型:定义策略执行时机
– 策略选项:定义策略选项
# 上下文规划
– 上下文名称:定义上下文名称
– 上下文属性:定义上下文属性
– 上下文值:定义上下文值
– 上下文作用域:定义上下文作用域
2.2 PDB虚拟私有数据库安全策略
Oracle PDB虚拟私有数据库安全策略:
- 最小权限原则:只授予必要的权限
- 职责分离:分离管理和审计职责
- 定期审计:审计VPD配置和使用
- 定期测试:定期测试访问控制策略
- 文档记录:记录VPD配置
– 识别敏感数据
– 定义策略函数和策略
– 配置上下文信息
– 定期审计和测试
– 文档记录配置
2.3 PDB虚拟私有数据库最佳实践
Oracle PDB虚拟私有数据库最佳实践:
- 数据分类:根据数据敏感程度分类
- 策略设计:合理设计策略函数
- 上下文设计:合理设计上下文信息
- 定期审计:审计VPD配置和使用
- 定期测试:定期测试访问控制策略
Part03-生产环境项目实施方案
3.1 PDB虚拟私有数据库配置
3.1.1 创建上下文
$ sqlplus / as sysdba
SQL> alter session set container=SALESPDB;
Session altered.
# 2. 创建上下文
SQL> create or replace context fgfgfgsales_ctx using fgfgfgsales_ctx_pkg;
Context created.
# 3. 验证上下文创建
SQL> select namespace, schema, package from dba_context where namespace = ‘SALES_CTX’;
NAMESPACE SCHEMA PACKAGE
———- ——— ———-
SALES_CTX SALES_CTX_PKG
# 4. 创建上下文管理包
SQL> create or replace package fgfgfgsales_ctx_pkg is
procedure set_dept_id(p_dept_id in number);
function get_dept_id return number;
end fgfgfgsales_ctx_pkg;
/
Package created.
SQL> create or replace package body fgfgfgsales_ctx_pkg is
procedure set_dept_id(p_dept_id in number) is
begin
dbms_session.set_context(‘SALES_CTX’, ‘DEPT_ID’, p_dept_id);
end set_dept_id;
function get_dept_id return number is
v_dept_id number;
begin
v_dept_id := sys_context(‘SALES_CTX’, ‘DEPT_ID’);
return v_dept_id;
end get_dept_id;
end fgfgfgsales_ctx_pkg;
/
Package body created.
# 5. 验证包创建
SQL> select object_name, object_type, status from user_objects where object_name = ‘SALES_CTX_PKG’;
OBJECT_NAME OBJECT_TYPE STATUS
————— ————- ——-
SALES_CTX_PKG PACKAGE VALID
SALES_CTX_PKG PACKAGE BODY VALID
3.1.2 创建策略函数
SQL> create user fgfgfgsales_user identified by fgfgfgsales_password;
User created.
SQL> grant create session, connect, resource to fgfgfgsales_user;
Grant succeeded.
SQL> create table fgfgfgsales_user.employees (
id number primary key,
name varchar2(100),
email varchar2(100),
dept_id number,
salary number,
hire_date date
);
Table created.
# 2. 插入测试数据
SQL> insert into fgfgfgsales_user.employees values (1, ‘风哥1号’, ‘zhangsan@fgedu.net.cn’, 10, 10000, sysdate – 365);
1 row created.
SQL> insert into fgfgfgsales_user.employees values (2, ‘风哥2号’, ‘lisi@fgedu.net.cn’, 10, 12000, sysdate – 300);
1 row created.
SQL> insert into fgfgfgsales_user.employees values (3, ‘王五’, ‘wangwu@fgedu.net.cn’, 20, 15000, sysdate – 200);
1 row created.
SQL> insert into fgfgfgsales_user.employees values (4, ‘赵六’, ‘zhaoliu@fgedu.net.cn’, 20, 18000, sysdate – 100);
1 row created.
SQL> insert into fgfgfgsales_user.employees values (5, ‘钱七’, ‘qianqi@fgedu.net.cn’, 30, 20000, sysdate – 50);
1 row created.
SQL> commit;
Commit complete.
# 3. 创建VPD策略函数
SQL> create or replace function fgfgfgsales_user.emp_dept_vpd_func(
p_schema in varchar2,
p_object in varchar2
) return varchar2 is
v_dept_id number;
v_predicate varchar2(200);
begin
v_dept_id := sys_context(‘SALES_CTX’, ‘DEPT_ID’);
if v_dept_id is null then
v_predicate := ‘1=0’;
else
v_predicate := ‘dept_id = ‘ || v_dept_id;
end if;
return v_predicate;
end emp_dept_vpd_func;
/
Function created.
# 4. 验证函数创建
SQL> select object_name, object_type, status from user_objects where object_name = ‘EMP_DEPT_VPD_FUNC’;
OBJECT_NAME OBJECT_TYPE STATUS
——————– ————- ——-
EMP_DEPT_VPD_FUNC FUNCTION VALID
3.2 PDB虚拟私有数据库策略创建
3.2.1 创建VPD策略
SQL> begin
dbms_rls.add_policy(
object_schema => ‘SALES_USER’,
object_name => ‘EMPLOYEES’,
policy_name => ‘EMP_DEPT_POLICY’,
function_schema => ‘SALES_USER’,
policy_function => ‘EMP_DEPT_VPD_FUNC’,
statement_types => ‘SELECT,INSERT,UPDATE,DELETE’,
enable => true
);
end;
/
PL/SQL procedure successfully completed.
# 2. 验证策略创建
SQL> select object_schema, object_name, policy_name, policy_function, enabled
from dba_policies
where object_schema = ‘SALES_USER’ and object_name = ‘EMPLOYEES’;
OBJECT_SCHEMA OBJECT_NAME POLICY_NAME POLICY_FUNCTION ENABLED
————- ———– —————– —————— ——–
SALES_USER EMPLOYEES EMP_DEPT_POLICY EMP_DEPT_VPD_FUNC YES
# 3. 测试VPD策略
SQL> conn fgfgfgsales_user/fgfgfgsales_password@SALESPDB
Connected.
SQL> select * from employees;
no rows selected
# 4. 设置上下文
SQL> exec fgfgfgsales_ctx_pkg.set_dept_id(10);
PL/SQL procedure successfully completed.
# 5. 再次测试VPD策略
SQL> select * from employees;
ID NAME EMAIL DEPT_ID SALARY HIRE_DATE
———- ———- ———————- ———- ———- ———
1 风哥1号 zhangsan@fgedu.net.cn 10 10000 31-MAR-25
2 风哥2号 lisi@fgedu.net.cn 10 12000 04-JUN-25
# 6. 清除上下文
SQL> exec fgfgfgsales_ctx_pkg.set_dept_id(null);
PL/SQL procedure successfully completed.
# 7. 再次测试VPD策略
SQL> select * from employees;
no rows selected
3.2.2 创建基于用户的VPD策略
SQL> conn / as sysdba
SQL> alter session set container=SALESPDB;
Session altered.
SQL> create user dept10_user identified by dept10_password;
User created.
SQL> create user dept20_user identified by dept20_password;
User created.
SQL> create user dept30_user identified by dept30_password;
User created.
SQL> grant create session, select on fgfgfgsales_user.employees to dept10_user;
Grant succeeded.
SQL> grant create session, select on fgfgfgsales_user.employees to dept20_user;
Grant succeeded.
SQL> grant create session, select on fgfgfgsales_user.employees to dept30_user;
Grant succeeded.
# 2. 创建基于用户的VPD策略函数
SQL> create or replace function fgfgfgsales_user.emp_user_vpd_func(
p_schema in varchar2,
p_object in varchar2
) return varchar2 is
v_username varchar2(100);
v_predicate varchar2(200);
begin
v_username := sys_context(‘USERENV’, ‘SESSION_USER’);
if v_username = ‘DEPT10_USER’ then
v_predicate := ‘dept_id = 10’;
elsif v_username = ‘DEPT20_USER’ then
v_predicate := ‘dept_id = 20’;
elsif v_username = ‘DEPT30_USER’ then
v_predicate := ‘dept_id = 30’;
else
v_predicate := ‘1=0’;
end if;
return v_predicate;
end emp_user_vpd_func;
/
Function created.
# 3. 创建基于用户的VPD策略
SQL> begin
dbms_rls.add_policy(
object_schema => ‘SALES_USER’,
object_name => ‘EMPLOYEES’,
policy_name => ‘EMP_USER_POLICY’,
function_schema => ‘SALES_USER’,
policy_function => ‘EMP_USER_VPD_FUNC’,
statement_types => ‘SELECT’,
enable => true
);
end;
/
PL/SQL procedure successfully completed.
# 4. 验证策略创建
SQL> select object_schema, object_name, policy_name, policy_function, enabled
from dba_policies
where object_schema = ‘SALES_USER’ and object_name = ‘EMPLOYEES’;
OBJECT_SCHEMA OBJECT_NAME POLICY_NAME POLICY_FUNCTION ENABLED
————- ———— —————– —————— ——–
SALES_USER EMPLOYEES EMP_DEPT_POLICY EMP_DEPT_VPD_FUNC YES
SALES_USER EMPLOYEES EMP_USER_POLICY EMP_USER_VPD_FUNC YES
# 5. 测试基于用户的VPD策略
SQL> conn dept10_user/dept10_password@SALESPDB
Connected.
SQL> select * from fgfgfgsales_user.employees;
ID NAME EMAIL DEPT_ID SALARY HIRE_DATE
———- ———- ———————- ———- ———- ———
1 风哥1号 zhangsan@fgedu.net.cn 10 10000 31-MAR-25
2 风哥2号 lisi@fgedu.net.cn 10 12000 04-JUN-25
SQL> conn dept20_user/dept20_password@SALESPDB
Connected.
SQL> select * from fgfgfgsales_user.employees;
ID NAME EMAIL DEPT_ID SALARY HIRE_DATE
———- ———- ———————- ———- ———- ———
3 王五 wangwu@fgedu.net.cn 20 15000 13-SEP-25
4 赵六 zhaoliu@fgedu.net.cn 20 18000 21-DEC-25
SQL> conn dept30_user/dept30_password@SALESPDB
Connected.
SQL> select * from fgfgfgsales_user.employees;
ID NAME EMAIL DEPT_ID SALARY HIRE_DATE
———- ———- ———————- ———- ———- ———
5 钱七 qianqi@fgedu.net.cn 30 20000 10-FEB-26
3.3 PDB虚拟私有数据库验证
3.3.1 验证VPD配置
SQL> conn / as sysdba
SQL> alter session set container=SALESPDB;
Session altered.
SQL> select object_schema, object_name, policy_name, policy_function, enabled
from dba_policies
where object_schema = ‘SALES_USER’ and object_name = ‘EMPLOYEES’;
OBJECT_SCHEMA OBJECT_NAME POLICY_NAME POLICY_FUNCTION ENABLED
————- ———— —————– —————— ——–
SALES_USER EMPLOYEES EMP_DEPT_POLICY EMP_DEPT_VPD_FUNC YES
SALES_USER EMPLOYEES EMP_USER_POLICY EMP_USER_VPD_FUNC YES
# 2. 查看VPD策略组
SQL> select object_schema, object_name, policy_group, policy_name
from dba_policies
where object_schema = ‘SALES_USER’ and object_name = ‘EMPLOYEES’;
OBJECT_SCHEMA OBJECT_NAME POLICY_GROUP POLICY_NAME
————- ———— ———— —————–
SALES_USER EMPLOYEES SYS_DEFAULT EMP_DEPT_POLICY
SALES_USER EMPLOYEES SYS_DEFAULT EMP_USER_POLICY
# 3. 查看VPD策略类型
SQL> select object_schema, object_name, policy_name, sel, ins, upd, del
from dba_policies
where object_schema = ‘SALES_USER’ and object_name = ‘EMPLOYEES’;
OBJECT_SCHEMA OBJECT_NAME POLICY_NAME SEL INS UPD DEL
————- ———— —————– — — — —
SALES_USER EMPLOYEES EMP_DEPT_POLICY YES YES YES YES
SALES_USER EMPLOYEES EMP_USER_POLICY YES NO NO NO
# 4. 查看上下文配置
SQL> select namespace, schema, package from dba_context where namespace = ‘SALES_CTX’;
NAMESPACE SCHEMA PACKAGE
———- ——— ———-
SALES_CTX SALES_CTX_PKG
# 5. 查看上下文属性
SQL> select namespace, attribute, value from v$context where namespace = ‘SALES_CTX’;
NAMESPACE ATTRIBUTE VALUE
———- ——— ———-
SALES_CTX DEPT_ID 10
3.3.2 管理VPD策略
SQL> begin
dbms_rls.enable_policy(
object_schema => ‘SALES_USER’,
object_name => ‘EMPLOYEES’,
policy_name => ‘EMP_DEPT_POLICY’,
enable => false
);
end;
/
PL/SQL procedure successfully completed.
# 2. 验证策略已禁用
SQL> select object_schema, object_name, policy_name, enabled
from dba_policies
where object_schema = ‘SALES_USER’ and object_name = ‘EMPLOYEES’;
OBJECT_SCHEMA OBJECT_NAME POLICY_NAME ENABLED
————- ———— —————– ——–
SALES_USER EMPLOYEES EMP_DEPT_POLICY NO
SALES_USER EMPLOYEES EMP_USER_POLICY YES
# 3. 启用VPD策略
SQL> begin
dbms_rls.enable_policy(
object_schema => ‘SALES_USER’,
object_name => ‘EMPLOYEES’,
policy_name => ‘EMP_DEPT_POLICY’,
enable => true
);
end;
/
PL/SQL procedure successfully completed.
# 4. 删除VPD策略
SQL> begin
dbms_rls.drop_policy(
object_schema => ‘SALES_USER’,
object_name => ‘EMPLOYEES’,
policy_name => ‘EMP_DEPT_POLICY’
);
end;
/
PL/SQL procedure successfully completed.
# 5. 验证策略已删除
SQL> select object_schema, object_name, policy_name, enabled
from dba_policies
where object_schema = ‘SALES_USER’ and object_name = ‘EMPLOYEES’;
OBJECT_SCHEMA OBJECT_NAME POLICY_NAME ENABLED
————- ———— ————— ——–
SALES_USER EMPLOYEES EMP_USER_POLICY YES
Part04-生产案例与实战讲解
4.1 PDB虚拟私有数据库配置案例
在生产环境中配置PDB虚拟私有数据库的完整案例:
4.1.1 场景描述
某企业需要为销售PDB中的员工数据配置VPD,确保每个部门只能查看本部门的员工信息,保护员工薪资等敏感信息。
4.1.2 配置步骤
SQL> conn / as sysdba
SQL> alter session set container=SALESPDB;
Session altered.
SQL> create or replace context emp_ctx using emp_ctx_pkg;
Context created.
# 2. 创建上下文管理包
SQL> create or replace package emp_ctx_pkg is
procedure set_dept_id(p_dept_id in number);
function get_dept_id return number;
end emp_ctx_pkg;
/
Package created.
SQL> create or replace package body emp_ctx_pkg is
procedure set_dept_id(p_dept_id in number) is
begin
dbms_session.set_context(‘EMP_CTX’, ‘DEPT_ID’, p_dept_id);
end set_dept_id;
function get_dept_id return number is
v_dept_id number;
begin
v_dept_id := sys_context(‘EMP_CTX’, ‘DEPT_ID’);
return v_dept_id;
end get_dept_id;
end emp_ctx_pkg;
/
Package body created.
# 3. 创建测试表
SQL> create user hr_admin identified by hr_password;
User created.
SQL> grant create session, connect, resource to hr_admin;
Grant succeeded.
SQL> create table hr_admin.employees (
id number primary key,
name varchar2(100),
email varchar2(100),
dept_id number,
salary number,
hire_date date
);
Table created.
# 4. 插入测试数据
SQL> insert into hr_admin.employees values (1, ‘风哥1号’, ‘zhangsan@fgedu.net.cn’, 10, 10000, sysdate – 365);
1 row created.
SQL> insert into hr_admin.employees values (2, ‘风哥2号’, ‘lisi@fgedu.net.cn’, 10, 12000, sysdate – 300);
1 row created.
SQL> insert into hr_admin.employees values (3, ‘王五’, ‘wangwu@fgedu.net.cn’, 20, 15000, sysdate – 200);
1 row created.
SQL> insert into hr_admin.employees values (4, ‘赵六’, ‘zhaoliu@fgedu.net.cn’, 20, 18000, sysdate – 100);
1 row created.
SQL> insert into hr_admin.employees values (5, ‘钱七’, ‘qianqi@fgedu.net.cn’, 30, 20000, sysdate – 50);
1 row created.
SQL> commit;
Commit complete.
# 5. 创建VPD策略函数
SQL> create or replace function hr_admin.emp_dept_vpd_func(
p_schema in varchar2,
p_object in varchar2
) return varchar2 is
v_dept_id number;
v_predicate varchar2(200);
begin
v_dept_id := sys_context(‘EMP_CTX’, ‘DEPT_ID’);
if v_dept_id is null then
v_predicate := ‘1=0’;
else
v_predicate := ‘dept_id = ‘ || v_dept_id;
end if;
return v_predicate;
end emp_dept_vpd_func;
/
Function created.
# 6. 创建VPD策略
SQL> begin
dbms_rls.add_policy(
object_schema => ‘HR_ADMIN’,
object_name => ‘EMPLOYEES’,
policy_name => ‘EMP_DEPT_POLICY’,
function_schema => ‘HR_ADMIN’,
policy_function => ‘EMP_DEPT_VPD_FUNC’,
statement_types => ‘SELECT,INSERT,UPDATE,DELETE’,
enable => true
);
end;
/
PL/SQL procedure successfully completed.
# 7. 验证配置
SQL> select object_schema, object_name, policy_name, policy_function, enabled
from dba_policies
where object_schema = ‘HR_ADMIN’ and object_name = ‘EMPLOYEES’;
OBJECT_SCHEMA OBJECT_NAME POLICY_NAME POLICY_FUNCTION ENABLED
————- ———— —————– —————— ——–
HR_ADMIN EMPLOYEES EMP_DEPT_POLICY EMP_DEPT_VPD_FUNC YES
# 8. 测试VPD策略
SQL> conn hr_admin/hr_password@SALESPDB
Connected.
SQL> select * from employees;
no rows selected
SQL> exec emp_ctx_pkg.set_dept_id(10);
PL/SQL procedure successfully completed.
SQL> select * from employees;
ID NAME EMAIL DEPT_ID SALARY HIRE_DATE
———- ———- ———————- ———- ———- ———
1 风哥1号 zhangsan@fgedu.net.cn 10 10000 31-MAR-25
2 风哥2号 lisi@fgedu.net.cn 10 12000 04-JUN-25
4.2 PDB虚拟私有数据库故障处理
在PDB虚拟私有数据库过程中可能遇到的故障及处理方法:
4.2.1 故障现象:查询返回空结果
SQL> conn hr_admin/hr_password@SALESPDB
Connected.
SQL> select * from employees;
no rows selected
# 分析步骤
# 1. 检查VPD策略
SQL> conn / as sysdba
SQL> alter session set container=SALESPDB;
Session altered.
SQL> select object_schema, object_name, policy_name, enabled
from dba_policies
where object_schema = ‘HR_ADMIN’ and object_name = ‘EMPLOYEES’;
OBJECT_SCHEMA OBJECT_NAME POLICY_NAME ENABLED
————- ———— —————– ——–
HR_ADMIN EMPLOYEES EMP_DEPT_POLICY YES
# 2. 检查上下文
SQL> select namespace, attribute, value from v$context where namespace = ‘EMP_CTX’;
no rows selected
# 3. 发现上下文未设置
# 4. 解决方案:设置上下文
SQL> conn hr_admin/hr_password@SALESPDB
Connected.
SQL> exec emp_ctx_pkg.set_dept_id(10);
PL/SQL procedure successfully completed.
# 5. 验证上下文已设置
SQL> select sys_context(‘EMP_CTX’, ‘DEPT_ID’) as dept_id from dual;
DEPT_ID
———-
10
# 6. 再次测试查询
SQL> select * from employees;
ID NAME EMAIL DEPT_ID SALARY HIRE_DATE
———- ———- ———————- ———- ———- ———
1 风哥1号 zhangsan@fgedu.net.cn 10 10000 31-MAR-25
2 风哥2号 lisi@fgedu.net.cn 10 12000 04-JUN-25
# 7. 预防措施
# – 配置自动设置上下文
# – 监控VPD策略状态
# – 定期测试访问控制
4.2.2 故障现象:ORA-28112策略函数错误
SQL> conn hr_admin/hr_password@SALESPDB
Connected.
SQL> select * from employees;
select * from employees
*
ERROR at line 1:
ORA-28112: failed to execute policy function
# 分析步骤
# 1. 检查策略函数
SQL> select object_name, object_type, status from user_objects where object_name = ‘EMP_DEPT_VPD_FUNC’;
OBJECT_NAME OBJECT_TYPE STATUS
——————– ————- ——-
EMP_DEPT_VPD_FUNC FUNCTION VALID
# 2. 测试策略函数
SQL> select hr_admin.emp_dept_vpd_func(‘HR_ADMIN’, ‘EMPLOYEES’) as predicate from dual;
PREDICATE
———–
dept_id = 10
# 3. 检查策略函数逻辑
SQL> select text from user_source where name = ‘EMP_DEPT_VPD_FUNC’ order by line;
TEXT
——————————————————————————–
function emp_dept_vpd_func(
p_schema in varchar2,
p_object in varchar2
) return varchar2 is
v_dept_id number;
v_predicate varchar2(200);
begin
v_dept_id := sys_context(‘EMP_CTX’, ‘DEPT_ID’);
if v_dept_id is null then
v_predicate := ‘1=0’;
else
v_predicate := ‘dept_id = ‘ || v_dept_id;
end if;
return v_predicate;
end emp_dept_vpd_func;
# 4. 发现函数逻辑正常
# 5. 检查VPD策略配置
SQL> select object_schema, object_name, policy_name, policy_function, enabled
from dba_policies
where object_schema = ‘HR_ADMIN’ and object_name = ‘EMPLOYEES’;
OBJECT_SCHEMA OBJECT_NAME POLICY_NAME POLICY_FUNCTION ENABLED
————- ———— —————– —————— ——–
HR_ADMIN EMPLOYEES EMP_DEPT_POLICY EMP_DEPT_VPD_FUNC YES
# 6. 尝试重新创建策略
SQL> begin
dbms_rls.drop_policy(
object_schema => ‘HR_ADMIN’,
object_name => ‘EMPLOYEES’,
policy_name => ‘EMP_DEPT_POLICY’
);
end;
/
PL/SQL procedure successfully completed.
SQL> begin
dbms_rls.add_policy(
object_schema => ‘HR_ADMIN’,
object_name => ‘EMPLOYEES’,
policy_name => ‘EMP_DEPT_POLICY’,
function_schema => ‘HR_ADMIN’,
policy_function => ‘EMP_DEPT_VPD_FUNC’,
statement_types => ‘SELECT,INSERT,UPDATE,DELETE’,
enable => true
);
end;
/
PL/SQL procedure successfully completed.
# 7. 再次测试查询
SQL> conn hr_admin/hr_password@SALESPDB
Connected.
SQL> exec emp_ctx_pkg.set_dept_id(10);
PL/SQL procedure successfully completed.
SQL> select * from employees;
ID NAME EMAIL DEPT_ID SALARY HIRE_DATE
———- ———- ———————- ———- ———- ———
1 风哥1号 zhangsan@fgedu.net.cn 10 10000 31-MAR-25
2 风哥2号 lisi@fgedu.net.cn 10 12000 04-JUN-25
# 8. 预防措施
# – 定期检查策略函数状态
# – 测试策略函数逻辑
# – 监控VPD策略错误
4.3 PDB虚拟私有数据库优化
优化PDB虚拟私有数据库配置的最佳实践:
4.3.1 优化VPD配置
SQL> create or replace function hr_admin.emp_salary_vpd_func(
p_schema in varchar2,
p_object in varchar2
) return varchar2 is
v_username varchar2(100);
v_predicate varchar2(200);
begin
v_username := sys_context(‘USERENV’, ‘SESSION_USER’);
if v_username = ‘HR_ADMIN’ then
v_predicate := ‘1=1’;
else
v_predicate := ‘salary <= 15000';
end if;
return v_predicate;
end emp_salary_vpd_func;
/
Function created.
SQL> begin
dbms_rls.add_policy(
object_schema => ‘HR_ADMIN’,
object_name => ‘EMPLOYEES’,
policy_name => ‘EMP_SALARY_POLICY’,
function_schema => ‘HR_ADMIN’,
policy_function => ‘EMP_SALARY_VPD_FUNC’,
statement_types => ‘SELECT’,
enable => true
);
end;
/
PL/SQL procedure successfully completed.
# 2. 验证多个VPD策略
SQL> select object_schema, object_name, policy_name, policy_function, enabled
from dba_policies
where object_schema = ‘HR_ADMIN’ and object_name = ‘EMPLOYEES’;
OBJECT_SCHEMA OBJECT_NAME POLICY_NAME POLICY_FUNCTION ENABLED
————- ———— ——————– ——————- ——–
HR_ADMIN EMPLOYEES EMP_DEPT_POLICY EMP_DEPT_VPD_FUNC YES
HR_ADMIN EMPLOYEES EMP_SALARY_POLICY EMP_SALARY_VPD_FUNC YES
# 3. 配置VPD审计
SQL> audit policy oracle_secure_config;
Audit succeeded.
# 4. 监控VPD策略
SQL> select object_schema, object_name, policy_name, enabled
from dba_policies
where object_schema = ‘HR_ADMIN’;
OBJECT_SCHEMA OBJECT_NAME POLICY_NAME ENABLED
————- ———— ——————– ——–
HR_ADMIN EMPLOYEES EMP_DEPT_POLICY YES
HR_ADMIN EMPLOYEES EMP_SALARY_POLICY YES
# 5. 创建VPD监控脚本
$ vi /home/oracle/scripts/monitor_vpd.sh
#!/bin/bash
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: http://www.fgedu.net.cn
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: http://www.fgedu.net.cn
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: http://www.fgedu.net.cn
# VPD监控脚本
export ORACLE_HOME=/oracle/app/oracle/product/19c/dbhome_1
export ORACLE_SID=FGEDUDB
export PATH=$ORACLE_HOME/bin:$PATH
# 检查VPD策略状态
POLICY_COUNT=$(sqlplus -s / as sysdba << EOF
set heading off feedback off pagesize 0
alter session set container=SALESPDB;
select count(*) from dba_policies where enabled = ‘NO’;
exit;
EOF
)
if [ “$POLICY_COUNT” -gt 0 ]; then
echo “WARNING: $POLICY_COUNT VPD policies are disabled”
# 发送告警
echo “$POLICY_COUNT VPD policies are disabled” | mail -s “VPD Policy Alert” admin@fgedu.net.cn
fi
# 检查VPD函数状态
FUNCTION_COUNT=$(sqlplus -s / as sysdba << EOF
set heading off feedback off pagesize 0
alter session set container=SALESPDB;
select count(*) from user_objects where object_type = ‘FUNCTION’ and status = ‘INVALID’;
exit;
EOF
)
if [ “$FUNCTION_COUNT” -gt 0 ]; then
echo “WARNING: $FUNCTION_COUNT VPD functions are invalid”
# 发送告警
echo “$FUNCTION_COUNT VPD functions are invalid” | mail -s “VPD Function Alert” admin@fgedu.net.cn
fi
echo “VPD monitoring completed at $(date)”
# 6. 设置定期监控
$ crontab -e
# 每小时检查VPD状态
0 * * * * /home/oracle/scripts/monitor_vpd.sh >> /home/oracle/scripts/monitor_vpd.log 2>&1
Part05-风哥经验总结与分享
5.1 PDB虚拟私有数据库总结
Oracle PDB虚拟私有数据库是行级别安全控制技术,具有以下特点:
- 数据保护:保护敏感数据的安全性
- 行级别安全:实现行级别访问控制
- 透明性:对应用程序透明
- 灵活性:支持灵活的访问控制
- 集中管理:集中管理访问控制策略
5.2 PDB虚拟私有数据库检查清单
Oracle PDB虚拟私有数据库检查清单:
- 配置检查:检查VPD策略配置
- 状态检查:检查VPD策略状态
- 函数检查:检查VPD策略函数
- 上下文检查:检查上下文配置
- 审计检查:检查VPD审计
- 监控检查:检查VPD监控
5.3 PDB虚拟私有数据库工具推荐
Oracle PDB虚拟私有数据库工具推荐:
- DBMS_RLS包:VPD管理包
- DBMS_SESSION包:会话管理包
- SQL*Plus:命令行工具,用于VPD管理
- SQL Developer:图形化工具,用于VPD管理
- Enterprise Manager:企业级管理工具
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
