如何在无WITH GRANT OPTION时跨Schema查询含系统字典的视图?
解决视图跨Schema访问的权限不足问题(无需WITH GRANT OPTION)
这是Oracle环境中典型的视图权限链问题——哪怕你给Schema B授予了视图V1和底层系统表的权限,但因为Schema A对底层表的权限不带WITH GRANT OPTION,导致B访问V1时权限检查失败。下面是几个不需要WITH GRANT OPTION的可行方案:
方案1:用角色统一管理权限
这是最安全且易维护的方案,通过角色把底层表权限同时赋予A和B,绕开权限传递的限制:
- 先让管理员创建一个专用角色,比如
ROLE_V1_DEPENDENCIES:CREATE ROLE ROLE_V1_DEPENDENCIES; - 给该角色授予底层系统表的查询权限:
GRANT SELECT ON dba_objects TO ROLE_V1_DEPENDENCIES; GRANT SELECT ON sys.$views TO ROLE_V1_DEPENDENCIES; - 将这个角色同时授予Schema A和Schema B:
GRANT ROLE_V1_DEPENDENCIES TO A; GRANT ROLE_V1_DEPENDENCIES TO B; - 最后让Schema A在启用该角色的状态下重新创建/刷新视图V1:
SET ROLE ROLE_V1_DEPENDENCIES; CREATE OR REPLACE VIEW A.V1 AS -- 原视图的查询语句 SELECT ... FROM dba_objects JOIN sys.$views ON ...;
原理:角色的权限是直接赋予用户的,并非通过A传递给B,所以B访问V1时,权限检查会直接验证自身的角色权限,不需要A的权限具备可传递性。
方案2:将视图改为定义者权限模式
Oracle默认视图是调用者权限(INVOKER'S RIGHTS),即访问视图时用当前用户(B)的权限访问底层表;改成**定义者权限(DEFINER'S RIGHTS)**后,会用视图所有者(A)的权限访问底层表,这样B只要有V1的查询权限即可,无需直接访问底层表:
- 修改已存在的视图:
ALTER VIEW A.V1 AUTHID DEFINER; - 或者创建视图时直接指定:
CREATE OR REPLACE VIEW A.V1 AUTHID DEFINER AS -- 原视图的查询语句 SELECT ... FROM dba_objects, sys.$views ...;
注意:这个方案要留意安全风险——相当于B借A的权限访问底层系统表,所以要确保A的权限是最小必要范围,避免过度授权。
为什么原授权方式无效?
Oracle的视图权限检查有两个核心规则:
- 调用者权限模式下,访问视图的用户(B)必须直接拥有底层表的权限;
- 同时,视图所有者(A)对底层表的权限必须带有
WITH GRANT OPTION,否则Oracle会判定A无权将底层表的访问权限通过视图传递给B。
这就是你给B授权了底层表和视图,却依然报权限不足的原因。
内容的提问来源于stack exchange,提问作者Алексей Байдин
相关产品推荐
相关产品推荐

