oracle中未显式设置default role时,所有已授角色均自动成为默认角色;必须用alter user显式指定,否则权限控制失效。

必须显式指定,否则所有已授角色都会成为默认角色——这是最常被忽略的配置点。
ALTER USER ... DEFAULT ROLE 的实际行为
执行 GRANT r1, r2, r3 TO u3 后,u3 登录即自动拥有全部三个角色权限,因为 Oracle 默认把所有已授予的角色都设为 DEFAULT。这不是“隐式启用”,而是默认策略:未显式设置 DEFAULT ROLE 时,全部已授角色生效。
要限制登录时只激活部分角色,必须用 ALTER USER 显式覆盖:
-
ALTER USER u3 DEFAULT ROLE r1;→ 只有r1生效,r2和r3不生效 -
ALTER USER u3 DEFAULT ROLE ALL EXCEPT r2;→r1、r3、r4生效,r2被排除 -
ALTER USER u3 DEFAULT ROLE NONE;→ 所有角色都不默认生效,必须手动SET ROLE
注意:DEFAULT ROLE 设置不改变授权关系,只控制登录时哪些角色权限自动加载。
带密码验证的角色不能设为 DEFAULT ROLE
如果角色创建时指定了密码(如 CREATE ROLE r2 IDENTIFIED BY r2;),它**无法**被包含在 DEFAULT ROLE 列表中。尝试执行:
ALTER USER u3 DEFAULT ROLE r1, r2;
会报错:ORA-01938: IDENTIFIED BY must be specified for CREATE USER(实际错误是 ORA-01935: missing user or role name 或更常见的是 ORA-01932: ADMIN option not granted for role 'r2',但根本原因是 Oracle 禁止将需验证的角色设为默认)。
解决方法只有两个:
- 改用无密码角色:
ALTER ROLE r2 NOT IDENTIFIED;,再设为 DEFAULT - 保留密码验证,但接受它只能通过
SET ROLE r2 IDENTIFIED BY r2;手动激活
SET ROLE 与 DEFAULT ROLE 的权限叠加逻辑
DEFAULT ROLE 是登录时一次性加载的权限集合;SET ROLE 是运行时切换当前会话的活跃角色集,会**完全替换**当前生效的角色,不是追加。
例如:
- 用户
u3的DEFAULT ROLE是r1 - 执行
SET ROLE r2 IDENTIFIED BY r2;→ 此时仅r2生效,r1权限丢失 - 执行
SET ROLE r1, r2 IDENTIFIED BY r2;→ 必须显式列出所有想激活的角色,且每个带密码的角色都要提供对应密码
Oracle 不支持“保留当前 + 新增一个”,必须全量声明。最大可同时激活角色数受参数 MAX_ENABLED_ROLES 限制(默认 150),超限会报 ORA-01924: role 'xxx' not granted or does not exist。
检查当前用户的 DEFAULT ROLE 设置
别依赖记忆或建库脚本,直接查数据字典:
SELECT granted_role, default_role FROM dba_role_privs WHERE grantee = 'U3';
其中 DEFAULT_ROLE = 'YES' 表示该角色当前是默认生效的。注意大小写敏感,用户名通常大写。
另外,SESSION_ROLES 视图反映的是当前会话实际生效的角色列表,可用于调试登录后权限是否符合预期:
SELECT * FROM SESSION_ROLES;
如果发现该视图为空,说明 DEFAULT ROLE NONE 且尚未执行任何 SET ROLE —— 这时连 SELECT 都可能报 ORA-00942: table or view does not exist,哪怕表确实存在,只是没权限访问。
真正容易出问题的地方在于:DBA 修改了 DEFAULT ROLE,但应用连接池没重连,旧会话仍维持着修改前的生效角色集;而新连接已按新规则加载。这种不一致会导致权限表现忽高忽低,排查时务必确认是“新会话”还是“复用连接”。











