注册
DM8 VPD 实践:行级访问控制原理
专栏/技术分享/ 文章详情 /

DM8 VPD 实践:行级访问控制原理

秧秧 2026/09/23 253 0 0
摘要

一、VPD 概述

1.1 什么是 VPD

VPD(Virtual Private Database,虚拟专用数据库)是数据库内置的行级安全机制。它通过在 SQL 执行前自动注入过滤条件,实现不同用户看到不同数据的效果,而无需修改应用程序代码。

1.2 VPD 解决什么问题

假设银行所有客户的账户信息都存放在同一张表里。客户A登录时只能看到自己的账户,客户B也只能看到自己的——这就是行级数据隔离。

传统做法:为每个客户创建视图,客户有100万时维护成本极高。

VPD做法:在表上绑定“自动过滤规则”,数据库自动追加 WHERE 条件,无需应用层改动。

1.3 VPD 与普通权限控制的区别

对比项 普通权限控制 VPD
控制粒度 表级/列级 行级
实现方式 GRANT/REVOKE 策略函数+谓词注入
应用感知 需要应用判断 应用无感知,数据库自动过滤
灵活性 静态 动态(策略函数可返回不同条件)

1.4 VPD 基本工作机制

用户执行SQL
    ↓
数据库调用策略函数 → 返回谓词(WHERE条件字符串)
    ↓
数据库自动将谓词追加到SQL中
    ↓
执行改写后的SQL → 返回过滤后的数据

核心组件:

  • 策略函数:返回字符串(谓词)的数据库函数
  • 谓词:策略函数返回的WHERE条件,如 ‘C1 < 3’
  • DBMS_RLS包:管理VPD策略(ADD_POLICY/ENABLE_POLICY/DROP_POLICY)

二、DM8 VPD 基础环境

2.1 测试环境

项目 内容
数据库版本 DM8 8.1.4.78
操作系统 麒麟 V10
关键参数 ENABLE_RLS=1

2.2 开启 VPD 并创建测试用户

-- 1. 开启VPD(静态参数,需重启) SP_SET_PARA_VALUE(2, 'ENABLE_RLS', 1); -- 重启数据库: systemctl restart DmServiceDMSERVER -- 2. 确认参数已生效 SELECT PARA_NAME, PARA_VALUE FROM V$DM_INI WHERE PARA_NAME = 'ENABLE_RLS'; -- 预期:ENABLE_RLS | 1 -- 3. 创建测试用户 DROP USER U01_VPD CASCADE; CREATE USER U01_VPD IDENTIFIED BY "U01_VPD_Abc"; GRANT DBA TO U01_VPD;

2.3 创建测试表

CONN U01_VPD/U01_VPD_Abc CREATE TABLE T01(C1 INT, C2 VARCHAR2(10)); INSERT INTO T01 VALUES(1,'A'); INSERT INTO T01 VALUES(2,'B'); INSERT INTO T01 VALUES(3,'C'); INSERT INTO T01 VALUES(4,'D'); INSERT INTO T01 VALUES(5,'E'); COMMIT;

2.4 创建 VPD 策略

CONN SYSDBA/Dameng123 -- 策略函数:只允许看到 C1 < 4 的数据 CREATE OR REPLACE FUNCTION FN_POLICY( P_OWNER IN VARCHAR2, P_OBJECT IN VARCHAR2 ) RETURN VARCHAR2 IS BEGIN RETURN 'C1 < 4'; END FN_POLICY; / -- 绑定策略到表(UPDATE_CHECK=TRUE) CALL DBMS_RLS.ADD_POLICY( OBJECT_SCHEMA => 'U01_VPD', OBJECT_NAME => 'T01', POLICY_NAME => 'POLICY_01', FUNCTION_SCHEMA => 'SYSDBA', POLICY_FUNCTION => 'FN_POLICY', STATEMENT_TYPES => 'SELECT,INSERT,UPDATE,DELETE,INDEX', UPDATE_CHECK => TRUE ); /

三、VPD 核心机制验证

3.1 SELECT 场景

CONN U01_VPD/U01_VPD_Abc -- 普通用户查询(受VPD限制) SELECT * FROM T01 ORDER BY C1; 行号 C1 C2 ---------- ----------- -- 1 1 A 2 2 B 3 3 C CONN SYSDBA/Dameng123 -- SYSDBA查询(绕过VPD,验证物理数据) SELECT * FROM U01_VPD.T01 ORDER BY C1; 行号 C1 C2 ---------- ----------- -- 1 1 A 2 2 B 3 3 C 4 4 D 5 5 E

核心验证方法:

  • 普通用户看到的是过滤后的数据
  • SYSDBA看到的是真实物理数据(SYSDBA不受VPD限制)

执行计划特征:

CONN U01_VPD/U01_VPD_Abc EXPLAIN SELECT * FROM T01; 1 #NSET2: [1, 1, 64] 2 #PRJT2: [1, 1, 64]; exp_num(3), is_atom(FALSE) 3 #PRJT2: [1, 1, 64]; exp_num(3), is_atom(FALSE) 4 #SLCT2: [1, 1, 64]; T01.C1 < 4 SLCT_PUSHDOWN(TRUE) 5 #CSCN2: [1, 5, 64]; INDEX33555520(T01) NEED_SLCT(TRUE); btr_scan(1)

3.2 INSERT 场景

-- 插入符合策略的数据(C1=3 < 4) INSERT INTO T01 VALUES(3, 'C'); 影响行数 1 -- 插入违反策略的数据(C1=6 >= 4) INSERT INTO T01 VALUES(6, 'F'); INSERT INTO T01 VALUES(6, 'F'); [-6614]:违反策略检查约束.

原因:UPDATE_CHECK=TRUE 要求新数据必须符合VPD策略。

3.3 UPDATE 场景

-- 更新为符合策略的值(C1=2, C2='X') UPDATE T01 SET C2='X' WHERE C1=2; 影响行数 1 -- 更新为违反策略的值(C1=2 -> C1=5) UPDATE T01 SET C1=5 WHERE C1=2; UPDATE T01 SET C1=5 WHERE C1=2; [-6614]:违反策略检查约束.

3.4 DELETE 场景

-- 删除符合策略的数据(C1=2) DELETE FROM T01 WHERE C1=2; 影响行数 1 -- 删除不可见的数据(C1=5,不在VPD可见范围内) DELETE FROM T01 WHERE C1=5; 影响行数 0

3.5 UPDATE_CHECK 机制

参数值 行为 业务场景
TRUE 新数据必须符合策略,否则报错 严格要求数据合规
FALSE 允许更新为不符合策略的值(更新后不可见) 软删除、数据归档

验证:设置 UPDATE_CHECK=FALSE 后,将数据更新为不符合策略的值会成功,但更新后用户看不到该数据。

四、小结

VPD 的本质是谓词注入。策略函数返回什么条件,执行计划中就会以相应的形式呈现。简单条件表现为 SLCT2,OR 条件展开为 UNION FOR OR2。无论哪种形式,只要谓词被正确附加,VPD 策略就已生效。

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服