在现代三层架构(Web Server - App Server - Database)中,数据库往往面临一个尴尬的局面:“我看不到真正的用户”。 成千上万的 Web 用户(如张三、李四)在访问应用,但应用服务器为了性能,使用了一个共享的连接池(Connection Pool)连接到数据库。对于数据库来说,所有的请求都来自同一个用户(比如 APP_SCHEMA)。 这直接导致两个严重问题:
- 审计失效:审计日志里全是 APP_SCHEMA 的操作记录,无法追溯究竟是张三还是李四删除了数据。
- 权限失控:数据库无法对张三和李四实施细粒度的权限控制,只能将逻辑写在应用代码里,容易产生安全漏洞。
Oracle 12c 引入的 RAS (Real Application Security) 正是为了解决这个“最后一公里”的身份丢失问题,实现端到端的安全管控。
01 什么是 RAS?
RAS 可视为 Oracle 虚拟专用数据库 (VPD/RLS) 的下一代进化版。它引入了一个全新的概念:应用用户 (Application User)。 这些用户无需在数据库里实际创建(不是 CREATE USER),而是作为轻量级的身份存在(通常从 LDAP 或应用同步)。
当应用服务器通过连接池连上数据库后,它会执行一个“轻量级会话附加”操作(XS_PRINCIPAL.SET_SESSION_USER),告诉数据库:“虽然连接是我(APP_SCHEMA)建立的,但现在正在操作的是张三。”
于是,数据库瞬间“看见”了张三,并能针对张三实施权限控制和审计。

图1:RAS 工作机制,实现从应用到数据库的端到端用户身份识别。
02 它的核心价值
1. 真正的端到端审计
在审计日志中,DBUSERNAME 依然是 APP_SCHEMA,但新增的 XS_USER_NAME 字段会清晰地显示 ZHANGSAN。终于可以精准追责了。
2. 声明式的数据安全 (Declarative Data Security)
你不再需要在 Java/PHP 代码里写 WHERE department_id = ... 这种容易出错的过滤逻辑。 你可以在数据库层定义数据安全策略(Data Security Policy),比如“销售经理只能看本部门的订单”。无论应用代码怎么写(甚至写了 SELECT *),数据库返回给张三的,永远只有他该看的数据。
3. 高性能
相比于传统的 VPD(通过触发器注入 SQL WHERE 子句),RAS 是内核级别的实现,且针对高并发连接池场景进行了深度优化,性能损耗极低。
03 怎么用?实战操作步骤
第一步:创建应用用户和角色
RAS 的用户和角色管理通过 XS_PRINCIPAL 包进行。
-- 1. 创建应用角色
EXEC XS_PRINCIPAL.CREATE_ROLE(name => 'SALES_MANAGER', enabled => TRUE);
-- 2. 创建应用用户 'zhangsan'
EXEC XS_PRINCIPAL.CREATE_USER(name => 'zhangsan', schema => 'HR');
-- 注意:schema => 'HR' 表示该用户主要访问 HR 模式下的对象,但他不是 HR 用户
-- 3. 设置密码(可选,如果由应用层认证则不需要)
EXEC XS_PRINCIPAL.SET_PASSWORD('zhangsan', 'Welcome1');
-- 4. 授予角色
EXEC XS_PRINCIPAL.GRANT_ROLES('zhangsan', 'SALES_MANAGER');
第二步:定义数据安全策略 (Data Security Policy)
我们要实现:销售经理只能查看金额小于 10000 的订单(假设)。
BEGIN
-- 1. 创建 ACL (访问控制列表)
-- 允许查看 (SELECT) 且满足特定条件
XS_ACL.CREATE_ACL(name => 'order_limit_acl', acl_type => XS_ACL.TYPE_DATA_SECURITY);
XS_ACL.ADD_ACL_PARAMETER(
acl => 'order_limit_acl',
policy => 'amount_policy', -- 策略名
privilege => 'SELECT',
owner => 'HR',
object_name => 'ORDERS',
entity_name => 'SALES_MANAGER', -- 针对销售经理角色
entity_type => XS_ACL.TYPE_ROLE,
principal_name => 'amount < 10000' -- 过滤条件 (这里简化演示)
);
-- 2. 将 ACL 应用到表上
XS_DATA_SECURITY.APPLY_OBJECT_POLICY(
policy => 'amount_policy',
schema => 'HR',
object => 'ORDERS',
acl => 'order_limit_acl'
);
END;
/
注:RAS 的策略配置非常灵活且强大,支持列级权限、行级过滤等。上述代码仅为逻辑示意,实际语法较为复杂,建议参考 Oracle 官方技术文档 或使用 Oracle Enterprise Manager (OEM) 图形化界面配置。
第三步:应用层集成 (Java 示例)
在 Java 代码中,当张三登录后,应用服务器从连接池获取连接,并切换身份。
// 获取 Oracle 连接
OracleConnection conn = (OracleConnection) dataSource.getConnection();
// 切换到应用用户 'zhangsan'
// 这不是建立新连接,而是轻量级会话切换
conn.attachSession("zhangsan", null);
// 执行查询
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM hr.orders");
// 此时,张三只能看到金额 < 10000 的订单
// 且审计日志中记录的是 zhangsan 的操作
04 进阶:与 TSDP 结合
RAS 可以和 TSDP 完美结合。TSDP 负责发现敏感列,RAS 负责控制谁能看这些列。 例如:TSDP 发现 CREDIT_CARD 列,RAS 策略定义“只有 FINANCE_MANAGER 角色可以查看该列明文,其他人看脱敏数据”。
05 总结与建议
RAS 是 Oracle 应对现代 Web 架构安全挑战的终极答案。它打破了应用层和数据库层的隔阂。
适用场景:
- 用户量巨大(数万+),无法在数据库为每个人建号。
- 使用连接池技术的 Web 应用。
- 对数据访问控制有极高要求的金融、政务系统。
实施建议:
RAS 的学习曲线较陡峭,建议先在非核心模块试点。对于全新的项目,强烈建议从设计阶段就引入 RAS,能极大简化应用层的权限代码开发。
结语
从权限分析、数据脱敏,到统一审计、TSDP,再到现在的 RAS,我们已经构建了一个相当完善的数据库安全体系。
但还有一个角落我们没有触及:加密。 如果黑客直接把服务器硬盘拔走了,或者把备份磁带偷走了,上述的所有防护(除了 TDE)可能都会失效。
参考资料
- Oracle Database 12c Real Application Security Administrator‘s and Developer’s Guide
- Oracle Application Security whitepapers