不能直接撤销CONNECT角色,因其是Oracle 19c中不可撤销的预定义系统角色(ORACLE_MAINTAINED),仅含CREATE SESSION权限;真正需清理的是用户被直接授予的冗余系统权限如CREATE TABLE、UNLIMITED TABLESPACE等。

直接撤销 CONNECT 角色不安全,也不可行——它已被 Oracle 标记为“不可撤销的预定义角色”,强行 REVOKE CONNECT FROM user 会报 ORA-01959: cannot revoke from role CONNECT。
为什么不能直接 REVOKE CONNECT?
Oracle 19c 中的 CONNECT 是系统内置的不可撤销角色(ROLE 类型为 YES 的 ORACLE_MAINTAINED),其存在意义是作为最小连接凭证的“占位符”,而非权限容器。从 10g 起,CONNECT 就已精简为仅含 CREATE SESSION;但很多旧环境仍残留着手动追加的权限(如 CREATE TABLE、UNLIMITED TABLESPACE),这才是真正需要清理的对象。
- 查当前用户是否被额外授了权限:
SELECT PRIVILEGE, ADMIN_OPTION FROM dba_sys_privs WHERE grantee = 'YOUR_USER' AND PRIVILEGE IN ('CREATE TABLE', 'CREATE VIEW', 'UNLIMITED TABLESPACE', 'SELECT ANY TABLE'); - 注意:
dba_role_privs里看到的CONNECT条目只是角色绑定,不反映实际权限来源;真正危险的是这些直接授予的系统权限。 - 不要依赖
DROP ROLE CONNECT或ALTER ROLE CONNECT NOT IDENTIFIED—— 这些语法在 19c 中无效,且可能破坏 CDB/PDB 兼容性。
如何定位并清理 CONNECT 用户的冗余系统权限?
重点不是动 CONNECT,而是剥离它不该有的“附加项”。生产中常见情况是 DBA 曾为图省事,把 CREATE TABLE 等权限直接授给了用户,而非通过 RESOURCE 或自定义角色管理。
- 列出该用户所有非角色来源的系统权限:
SELECT PRIVILEGE, ADMIN_OPTION, GRANTABLE FROM dba_sys_privs WHERE grantee = 'YOUR_USER' AND NOT EXISTS (SELECT 1 FROM dba_role_privs r WHERE r.grantee = dba_sys_privs.grantee AND r.granted_role = 'CONNECT'); - 逐条撤销高风险权限,例如:
REVOKE CREATE TABLE FROM YOUR_USER;、REVOKE UNLIMITED TABLESPACE FROM YOUR_USER; - 如果用户确实需要建表等能力,应改用显式角色:
CREATE ROLE app_developer; GRANT CREATE TABLE, CREATE SEQUENCE TO app_developer; GRANT app_developer TO YOUR_USER; - 特别注意
ADMIN_OPTION = 'YES'的权限——它允许用户再转授,必须优先清理,否则权限扩散不可控。
撤销后必须验证的三个关键点
权限删完不等于生效,尤其在多租户或有中间件缓存的场景下,容易误判。
- 登录后立即执行:
SELECT * FROM session_privs;—— 这是当前会话真实拥有的系统权限,不含角色继承,最准。 - 检查表空间配额是否仍为
UNLIMITED:SELECT username, tablespace_name, bytes/1024/1024 MB FROM dba_ts_quotas WHERE username = 'YOUR_USER';,若仍无限,需补ALTER USER YOUR_USER QUOTA 0 ON users; - 测试典型操作是否失败:
CREATE TABLE t(x INT);应报ORA-01031: insufficient privileges;而SELECT 1 FROM DUAL;必须成功(CREATE SESSION仍在)。
真正难的不是执行 REVOKE 命令,而是厘清“这个用户到底靠什么权限在干活”——它可能来自角色、角色的角色、直接授予、PUBLIC、甚至 DBLINK 所依赖的同义词。别只盯着 CONNECT 看,先跑一遍 dba_sys_privs + dba_tab_privs + dba_role_privs 三查,否则删掉一个权限,业务就挂一个接口。


















