查不到“通过角色继承的权限”是因为只查user_sys_privs等直授视图,需结合角色递归与权限关联才能追溯完整路径,如dba→resource→用户。

查不到“通过角色继承的权限”,基本是因为只查了 USER_SYS_PRIVS 或 USER_TAB_PRIVS_RECD 这类直授视图——它们不展开角色链。必须用角色递归+权限关联两步走,才能看到“这个 SELECT 权限,其实是从 DBA 角色 → RESOURCE 角色 → 你”这条路径。
查当前用户所有系统权限(含角色继承)
普通用户能跑的最全汇总,但不带来源路径:
直接执行以下语句即可得到去重后的全部系统权限名:
SELECT DISTINCT privilege FROM ( SELECT privilege FROM user_sys_privs UNION ALL SELECT rp.privilege FROM role_sys_privs rp WHERE rp.role IN (SELECT granted_role FROM user_role_privs) ) ORDER BY privilege;
注意:user_role_privs 只返回直授角色,不包含间接继承的角色(比如 A→B→你,这里只看到 B);所以这个结果是“你有啥权限”,不是“这权限从哪来”。
常见坑:
-
user_sys_privs里出现的权限,说明是直接授予用户的,和角色无关 - 如果某角色被授予但
DEFAULT_ROLE为FALSE,且没执行SET ROLE,该角色携带的权限不会出现在会话中 - 12c+ 版本中,
DELEGATE OPTION决定你能否把角色再授给别人,但它不影响你自己的权限可见性
查某个角色具体带哪些系统权限
知道角色名后,快速确认它打包了什么能力,避免盲目授权:
例如查 RESOURCE 角色包含哪些系统权限:
SELECT privilege, admin_option FROM role_sys_privs WHERE role = 'RESOURCE';
关键点:
-
admin_option = 'YES'表示你拿到这个角色后,还能用GRANT ... WITH ADMIN OPTION把该角色再授给别人 - 不同 Oracle 版本内置角色权限不同(如 19c 的
CONNECT已大幅瘦身),不能凭经验猜 - 自定义角色可能嵌套多层,单查这一层不够,得配合
ROLE_ROLE_PRIVS往上挖
查角色继承链:谁把哪个角色给了你
要定位权限源头,必须从 user_role_privs 出发,逐层向上追溯角色授予关系:
执行以下递归查询(需注意方向):
SELECT LEVEL, granted_role, grantee FROM role_role_privs START WITH grantee IN ( SELECT granted_role FROM user_role_privs ) CONNECT BY PRIOR granted_role = grantee;
说明:
- 结果中
grantee是“被授角色者”,granted_role是“被授予的角色”——方向容易看反 - 第一层(
LEVEL = 1)是你直接受授的角色;第二层是你所拥有角色又授予了谁(即向下传播),不是向上溯源 - 真正想查“谁给了你这个角色”,得反向查
DBA_ROLE_PRIVS(需 DBA 权限),或用USER_ROLE_PRIVS+ 手动比对ROLE_ROLE_PRIVS中的上级节点 - 若出现循环(如角色 A 授予自己),会报
ORA-01436: CONNECT BY loop,需加NOCYCLE并用CONNECT_BY_ISCYCLE过滤
查对象权限继承路径(表/视图级)
对象权限(如对某张表的 SELECT)也能通过角色继承,但路径更隐蔽:
先确认角色是否带该对象权限:
SELECT owner, table_name, privilege, grantable FROM role_tab_privs WHERE role IN (SELECT granted_role FROM user_role_privs) AND table_name = 'EMP';
再结合 ROLE_ROLE_PRIVS 查这个角色本身是不是被其他角色授予的——只有当角色 A 被 B 授予,且 A 有对 EMP 的 SELECT 权限,你才真正“继承”到了它。
容易忽略的细节:
-
role_tab_privs不区分权限是否可转授(grantable字段只对直接授予有效) - 如果权限来自角色,但该角色未设为
DEFAULT_ROLE,且你没运行SET ROLE,这条权限在当前会话不可用 - 跨 schema 的对象权限(如
SCOTT.EMP)必须显式写出 owner,否则查不到
角色继承不是单线树,而是有向图;一个权限可能来自多条路径,人工梳理超过三层就容易漏。真要定位某条权限的生效源头,得把 SESSION_ROLES、USER_ROLE_PRIVS、ROLE_ROLE_PRIVS 和 ROLE_SYS_PRIVS 四张表串起来手工对齐——没有一键视图能自动画出完整继承图谱。











