Part01-基础概念与理论知识
1.1 VPD策略的概念
VPD策略是Oracle数据库中用于实现行级访问控制的安全机制,它通过在用户执行SQL语句时自动添加WHERE子句,过滤掉用户无权访问的数据行。
学习交流加群风哥QQ113257174
1.2 VPD策略的类型
- 基于函数的VPD策略:使用函数返回过滤条件
- 基于上下文的VPD策略:使用应用上下文存储用户信息
- 基于角色的VPD策略:根据用户角色过滤数据
- 基于时间的VPD策略:根据时间条件过滤数据
风哥提示:不同类型的VPD策略可以结合使用,实现更复杂的访问控制
1.3 VPD策略的组成部分
- 策略名称:唯一标识VPD策略
- 对象模式:应用策略的模式
- 对象名称:应用策略的表或视图
- 策略函数:返回过滤条件的函数
- 语句类型:应用策略的SQL语句类型
- 策略类型:策略的应用方式
更多视频教程www.fgedu.net.cn
Part02-生产环境规划与建议
2.1 VPD策略设计原则
- 最小权限原则:只授予用户必要的数据访问权限
- 明确的策略目标:每个策略应该有明确的安全目标
- 可维护性:策略应该易于理解和维护
- 性能考虑:策略不应该显著影响数据库性能
2.2 VPD策略性能考虑
在生产环境中,VPD策略可能会对性能产生影响,建议:
- 优化策略函数,避免复杂的逻辑
- 为过滤条件创建适当的索引
- 限制策略的应用范围,只对必要的表应用策略
- 定期监控策略的性能影响
学习交流加群风哥微信: itpux-com
2.3 VPD策略管理最佳实践
- 使用命名规范:为策略使用有意义的名称
- 文档化策略:记录策略的目的和实现
- 定期审查策略:确保策略仍然满足安全需求
- 测试策略变更:在生产环境变更前进行测试
更多学习教程公众号风哥教程itpux_com
Part03-生产环境项目实施方案
风哥教程参考Oracle官方文档Security部分,我们将实施以下步骤:
- 创建测试环境
- 设计VPD策略
- 实现策略函数
- 应用VPD策略
- 测试策略效果
- 监控策略性能
from oracle:www.itpux.com
Part04-生产案例与实战讲解
4.1 创建测试表
命令:CREATE TABLE fgedu.fgsales (
sale_id NUMBER(10),
product_id NUMBER(6),
salesperson_id NUMBER(6),
customer_id NUMBER(6),
sale_date DATE,
amount NUMBER(10,2),
region VARCHAR2(20)
);INSERT INTO fgedu.fgsales VALUES (1, 100, 101, 201, SYSDATE-30, 1000, ‘North’);INSERT INTO fgedu.fgsales VALUES (2, 101, 101, 202, SYSDATE-25, 1500, ‘North’);INSERT INTO fgedu.fgsales VALUES (3, 102, 102, 203, SYSDATE-20, 2000, ‘South’);INSERT INTO fgedu.fgsales VALUES (4, 103, 102, 204, SYSDATE-15, 2500, ‘South’);INSERT INTO fgedu.fgsales VALUES (5, 104, 103, 205, SYSDATE-10, 3000, ‘East’);COMMIT;执行:输出日志:Table created.1 row created.1 row created.1 row created.1 row created.1 row created.Commit complete.
sale_id NUMBER(10),
product_id NUMBER(6),
salesperson_id NUMBER(6),
customer_id NUMBER(6),
sale_date DATE,
amount NUMBER(10,2),
region VARCHAR2(20)
);INSERT INTO fgedu.fgsales VALUES (1, 100, 101, 201, SYSDATE-30, 1000, ‘North’);INSERT INTO fgedu.fgsales VALUES (2, 101, 101, 202, SYSDATE-25, 1500, ‘North’);INSERT INTO fgedu.fgsales VALUES (3, 102, 102, 203, SYSDATE-20, 2000, ‘South’);INSERT INTO fgedu.fgsales VALUES (4, 103, 102, 204, SYSDATE-15, 2500, ‘South’);INSERT INTO fgedu.fgsales VALUES (5, 104, 103, 205, SYSDATE-10, 3000, ‘East’);COMMIT;执行:输出日志:Table created.1 row created.1 row created.1 row created.1 row created.1 row created.Commit complete.
4.2 创建应用上下文
命令:CREATE CONTEXT fgedu_sales_ctx USING fgedu_sales_ctx_pkg;执行:输出日志:Context created.
4.3 创建上下文包
命令:CREATE OR REPLACE PACKAGE fgedu_sales_ctx_pkg AS
PROCEDURE set_context(p_user VARCHAR2, p_salesperson_id NUMBER, p_region VARCHAR2);END fgedu_sales_ctx_pkg;/CREATE OR REPLACE PACKAGE BODY fgedu_sales_ctx_pkg AS
PROCEDURE set_context(p_user VARCHAR2, p_salesperson_id NUMBER, p_region VARCHAR2) IS
BEGIN
DBMS_SESSION.SET_CONTEXT(‘fgedu_sales_ctx’, ‘user_id’, p_user);DBMS_SESSION.SET_CONTEXT(‘fgedu_sales_ctx’, ‘salesperson_id’, p_salesperson_id);DBMS_SESSION.SET_CONTEXT(‘fgedu_sales_ctx’, ‘region’, p_region);END set_context;END fgedu_sales_ctx_pkg;/执行:输出日志:Package created.Package body created.
PROCEDURE set_context(p_user VARCHAR2, p_salesperson_id NUMBER, p_region VARCHAR2);END fgedu_sales_ctx_pkg;/CREATE OR REPLACE PACKAGE BODY fgedu_sales_ctx_pkg AS
PROCEDURE set_context(p_user VARCHAR2, p_salesperson_id NUMBER, p_region VARCHAR2) IS
BEGIN
DBMS_SESSION.SET_CONTEXT(‘fgedu_sales_ctx’, ‘user_id’, p_user);DBMS_SESSION.SET_CONTEXT(‘fgedu_sales_ctx’, ‘salesperson_id’, p_salesperson_id);DBMS_SESSION.SET_CONTEXT(‘fgedu_sales_ctx’, ‘region’, p_region);END set_context;END fgedu_sales_ctx_pkg;/执行:输出日志:Package created.Package body created.
4.4 创建策略函数
命令:CREATE OR REPLACE FUNCTION fgedu_sales_policy_fn(
p_schema IN VARCHAR2,
p_object IN VARCHAR2
) RETURN VARCHAR2 IS
l_salesperson_id NUMBER;l_region VARCHAR2(20);l_predicate VARCHAR2(2000);BEGIN
l_salesperson_id := SYS_CONTEXT(‘fgedu_sales_ctx’, ‘salesperson_id’);l_region := SYS_CONTEXT(‘fgedu_sales_ctx’, ‘region’);IF l_salesperson_id IS NOT NULL THEN
l_predicate := ‘salesperson_id = ‘ || l_salesperson_id;ELSIF l_region IS NOT NULL THEN
l_predicate := ‘region = ”’ || l_region || ””;ELSE
l_predicate := ‘1=2’; — 无权限访问任何数据
END IF;RETURN l_predicate;END fgedu_sales_policy_fn;/执行:输出日志:Function created.
p_schema IN VARCHAR2,
p_object IN VARCHAR2
) RETURN VARCHAR2 IS
l_salesperson_id NUMBER;l_region VARCHAR2(20);l_predicate VARCHAR2(2000);BEGIN
l_salesperson_id := SYS_CONTEXT(‘fgedu_sales_ctx’, ‘salesperson_id’);l_region := SYS_CONTEXT(‘fgedu_sales_ctx’, ‘region’);IF l_salesperson_id IS NOT NULL THEN
l_predicate := ‘salesperson_id = ‘ || l_salesperson_id;ELSIF l_region IS NOT NULL THEN
l_predicate := ‘region = ”’ || l_region || ””;ELSE
l_predicate := ‘1=2’; — 无权限访问任何数据
END IF;RETURN l_predicate;END fgedu_sales_policy_fn;/执行:输出日志:Function created.
4.5 创建VPD策略
命令:EXEC DBMS_RLS.ADD_POLICY(
object_schema => ‘fgedu’,
object_name => ‘fgsales’,
policy_name => ‘fgedu_sales_policy’,
function_schema => ‘fgedu’,
policy_function => ‘fgedu_sales_policy_fn’,
statement_types => ‘SELECT, INSERT, UPDATE, DELETE’,
update_check => TRUE
);执行:输出日志:PL/SQL procedure successfully completed.
object_schema => ‘fgedu’,
object_name => ‘fgsales’,
policy_name => ‘fgedu_sales_policy’,
function_schema => ‘fgedu’,
policy_function => ‘fgedu_sales_policy_fn’,
statement_types => ‘SELECT, INSERT, UPDATE, DELETE’,
update_check => TRUE
);执行:输出日志:PL/SQL procedure successfully completed.
4.6 测试VPD策略
命令:— 设置上下文为销售人员101
EXEC fgedu_sales_ctx_pkg.set_context(‘SALESPERSON_101’, 101, NULL);– 查询销售数据
SELECT sale_id, product_id, amount, region FROM fgedu.fgsales;执行:输出日志:PL/SQL procedure successfully completed.SALE_ID PRODUCT_ID AMOUNT REGION
———- ———- ———- —— 1 100 1000 North 2 101 1500 North
EXEC fgedu_sales_ctx_pkg.set_context(‘SALESPERSON_101’, 101, NULL);– 查询销售数据
SELECT sale_id, product_id, amount, region FROM fgedu.fgsales;执行:输出日志:PL/SQL procedure successfully completed.SALE_ID PRODUCT_ID AMOUNT REGION
———- ———- ———- —— 1 100 1000 North 2 101 1500 North
4.7 测试区域过滤
命令:— 设置上下文为区域South
EXEC fgedu_sales_ctx_pkg.set_context(‘REGION_SOUTH’, NULL, ‘South’);– 查询销售数据
SELECT sale_id, product_id, amount, region FROM fgedu.fgsales;执行:输出日志:PL/SQL procedure successfully completed.SALE_ID PRODUCT_ID AMOUNT REGION
———- ———- ———- —— 3 102 2000 South 4 103 2500 South
EXEC fgedu_sales_ctx_pkg.set_context(‘REGION_SOUTH’, NULL, ‘South’);– 查询销售数据
SELECT sale_id, product_id, amount, region FROM fgedu.fgsales;执行:输出日志:PL/SQL procedure successfully completed.SALE_ID PRODUCT_ID AMOUNT REGION
———- ———- ———- —— 3 102 2000 South 4 103 2500 South
风哥提示:VPD策略可以根据不同的上下文信息实现灵活的数据过滤
4.8 管理VPD策略
命令:— 查看VPD策略
SELECT policy_name, object_name, function_name, statement_types
FROM all_policies
WHERE object_owner = ‘FGEDU’;– 修改VPD策略
EXEC DBMS_RLS.ALTER_POLICY(
object_schema => ‘fgedu’,
object_name => ‘fgsales’,
policy_name => ‘fgedu_sales_policy’,
statement_types => ‘SELECT, INSERT, UPDATE’
);– 删除VPD策略
EXEC DBMS_RLS.DROP_POLICY(‘fgedu’, ‘fgsales’, ‘fgedu_sales_policy’);执行:输出日志:POLICY_NAME OBJECT_NAME FUNCTION_NAME STATEMENT_TYPES
——————– ————— ——————– ——————–
FGEDU_SALES_POLICY SALES FGEDU_SALES_POLICY_FN SELECT,INSERT,UPDATE,DELETEPL/SQL procedure successfully completed.PL/SQL procedure successfully completed.
SELECT policy_name, object_name, function_name, statement_types
FROM all_policies
WHERE object_owner = ‘FGEDU’;– 修改VPD策略
EXEC DBMS_RLS.ALTER_POLICY(
object_schema => ‘fgedu’,
object_name => ‘fgsales’,
policy_name => ‘fgedu_sales_policy’,
statement_types => ‘SELECT, INSERT, UPDATE’
);– 删除VPD策略
EXEC DBMS_RLS.DROP_POLICY(‘fgedu’, ‘fgsales’, ‘fgedu_sales_policy’);执行:输出日志:POLICY_NAME OBJECT_NAME FUNCTION_NAME STATEMENT_TYPES
——————– ————— ——————– ——————–
FGEDU_SALES_POLICY SALES FGEDU_SALES_POLICY_FN SELECT,INSERT,UPDATE,DELETEPL/SQL procedure successfully completed.PL/SQL procedure successfully completed.
更多视频教程www.fgedu.net.cn
Part05-风哥经验总结与分享
5.1 最佳实践
- 使用应用上下文存储用户信息,提高安全性和灵活性
- 合理设计策略函数,避免复杂的逻辑影响性能
- 为VPD过滤条件创建适当的索引,提高查询性能
- 定期审查VPD策略,确保权限控制合理
5.2 常见问题与解决方案
- 问题:VPD策略影响性能
解决方案:优化策略函数,创建适当的索引 - 问题:策略函数返回错误的过滤条件
解决方案:仔细测试策略函数,确保返回正确的条件 - 问题:应用上下文未正确设置
解决方案:确保在访问数据前正确设置上下文
学习交流加群风哥QQ113257174
5.3 性能优化
- 使用绑定变量,减少硬解析
- 避免在策略函数中执行复杂查询
- 考虑使用Oracle的分区功能,减少VPD的开销
- 定期监控VPD对性能的影响
更多学习教程公众号风哥教程itpux_com
5.4 安全建议
- 使用强密码保护VPD相关的包和函数
- 限制对VPD策略的修改权限
- 定期审计VPD策略的使用情况
- 结合其他安全特性,如审计和数据加密
from oracle:www.itpux.com
