Oracle数据库的权限体系一直是初学者容易混淆的部分。一个用户登录数据库后能做什么、不能做什么,完全取决于它被授予了哪些权限。权限给得太宽,可能一个误操作就删掉整张业务表;给得太窄,应用又会频繁报权限不足的错误。这篇文章从实战角度出发,把用户创建、权限授予、权限回收这一整套流程讲透,并给出生产环境的管理建议。

一、先理清概念:用户、权限、角色之间的关系
很多初学者一开始就急着敲GRANT语句,结果发现授权之后还是各种报错,根源在于没有理清几个基本概念。Oracle中的权限分为两大类:系统权限(System Privilege)和对象权限(Object Privilege)。系统权限控制的是“能不能做某一类操作”,比如创建会话、创建表、删除任意用户;对象权限控制的是“能不能对某个具体对象做操作”,比如查询某张表、更新某个视图。
角色则是权限的集合。你可以把一组常用的权限打包成一个角色,再把角色授予多个用户,这样就不用对每个用户重复执行几十条GRANT语句。Oracle内置了一些常用角色,比如CONNECT、RESOURCE、DBA。CONNECT包含最基本的建会话权限,RESOURCE包含建表、建序列等开发常用权限,而DBA则是数据库管理员的超大权限集合,业务账号一般不要授予它。
需要特别说明的是,Oracle的权限授予支持WITH ADMIN OPTION和WITH GRANT OPTION两种传递方式,前者针对系统权限和角色,后者针对对象权限,两者的回收行为差异很大,后面会详细对比。
二、用户创建与基础配置
创建用户使用CREATE USER语句,通常由DBA账号(如SYSTEM)执行。一个完整的建用户语句包含用户名、认证方式、默认表空间和配额设置:
-- 创建业务用户 CREATE USER app_user IDENTIFIED BY "YourPwd@2024" DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp QUOTA 500M ON users ACCOUNT UNLOCK; -- 修改用户密码 ALTER USER app_user IDENTIFIED BY "NewPwd@2024"; -- 锁定与解锁账号 ALTER USER app_user ACCOUNT LOCK; ALTER USER app_user ACCOUNT UNLOCK; -- 设置密码过期,强制用户首次登录修改密码 ALTER USER app_user PASSWORD EXPIRE;
建完用户后直接登录会报错,提示缺少CREATE SESSION权限,这是最常见的坑之一。Oracle不会给新用户任何默认权限,必须显式授予。QUOTA子句用来限制用户在表空间上的磁盘使用量,如果建表时报ORA-01950错误(对表空间无权限),大概率就是没有分配配额。
密码方面建议使用复杂密码并用双引号包裹,避免特殊字符引发解析问题。生产环境还建议开启密码策略配置,比如通过PROFILE限制密码失效天数、失败登录次数等:
-- 创建资源限制配置 CREATE PROFILE app_profile LIMIT FAILED_LOGIN_ATTEMPTS 5 PASSWORD_LIFE_TIME 90 PASSWORD_REUSE_MAX 5 PASSWORD_LOCK_TIME 1/24; -- 将配置绑定到用户 ALTER USER app_user PROFILE app_profile;
三、GRANT授权的完整用法
授权分为三种情况:授系统权限、授对象权限、授角色。三者的语法略有差别,下面分别演示。
1. 授予系统权限和角色
-- 授予登录和开发基础权限 GRANT CREATE SESSION, CREATE TABLE, CREATE VIEW, CREATE SEQUENCE TO app_user; -- 授予内置角色 GRANT CONNECT, RESOURCE TO app_user; -- 带管理选项授权,允许app_user再把该权限授予他人 GRANT CREATE ANY TABLE TO app_user WITH ADMIN OPTION;
WITH ADMIN OPTION要谨慎使用,它意味着该用户可以继续向下传递权限,甚至回收别人的权限。审计要求严格的系统里,这种传递链条很容易失控,一般只授予DBA管理账号。
2. 授予对象权限
-- 授予查询和更新权限 GRANT SELECT, UPDATE ON scott.emp TO app_user; -- 授予所有对象权限 GRANT ALL ON scott.dept TO app_user; -- 允许被授权者继续传递该权限 GRANT SELECT ON scott.emp TO app_user WITH GRANT OPTION; -- 授予某个存储过程的执行权限 GRANT EXECUTE ON scott.calc_salary TO app_user;
对象权限还可以细化到列级别,比如只允许用户更新某张表的特定列:GRANT UPDATE (sal, comm) ON scott.emp TO app_user;。这种粒度在需要给第三方系统开放部分字段的场景中非常实用。
3. 使用角色批量授权
-- 创建自定义角色 CREATE ROLE dev_role; -- 给角色授予权限 GRANT CREATE SESSION, CREATE TABLE, CREATE VIEW TO dev_role; GRANT SELECT ON scott.emp TO dev_role; -- 把角色授予多个用户 GRANT dev_role TO dev_user1, dev_user2;
角色最大的价值在于批量变更:当业务调整需要新增某个权限时,只需对角色执行一次GRANT,所有持有该角色的用户立即生效,不用逐个用户修改。建议按职能划分角色,比如开发角色、只读查询角色、运维角色,用户与权限解耦后管理成本会大幅下降。
四、REVOKE回收权限与传递性差异
回收权限使用REVOKE语句,基本语法和GRANT对称:
-- 回收系统权限 REVOKE CREATE TABLE FROM app_user; -- 回收对象权限 REVOKE SELECT ON scott.emp FROM app_user; -- 回收角色 REVOKE dev_role FROM dev_user1;
这里有一个非常重要的知识点:系统权限和对象权限的级联回收行为完全不同。回收系统权限时,如果是通过WITH ADMIN OPTION传递出去的,下游用户的权限不会受影响,仍然保留;而回收对象权限时,通过WITH GRANT OPTION传递出去的权限会被级联回收,下游用户会一并失去权限。这个差异在面试和实际运维中都经常被考到,务必记住。
五、如何查询用户拥有的权限
授权之后需要验证,Oracle提供了一组数据字典视图供查询:
-- 查看当前用户的系统权限 SELECT * FROM user_sys_privs; -- 查看当前用户的对象权限 SELECT * FROM user_tab_privs; -- 查看当前用户的角色 SELECT * FROM user_role_privs; -- DBA视角查看指定用户的全部权限 SELECT * FROM dba_sys_privs WHERE grantee = 'APP_USER'; SELECT * FROM dba_role_privs WHERE grantee = 'APP_USER'; SELECT grantee, privilege, table_name FROM dba_tab_privs WHERE grantee = 'APP_USER'; -- 查看角色中包含哪些权限 SELECT * FROM role_sys_privs WHERE role = 'DEV_ROLE';
排查权限问题时,通常先查角色,再查角色内包含的权限,因为很多权限是通过角色间接获得的。另外要注意PUBLIC这个特殊用户,授予PUBLIC的权限所有用户都拥有,审计时可以用SELECT * FROM dba_tab_privs WHERE grantee = 'PUBLIC';检查是否存在越权风险。
六、生产环境权限管理规范建议
结合实际的运维经验,给出几条比较实用的规范。第一,业务应用账号只授最小权限,一般CONNECT加RESOURCE再加必要的对象权限就够了,绝不能图省事直接给DBA角色,历史上不少删库事故都源于此。第二,开发、测试、生产环境的账号严格分开,不要用同一个账号连接多套环境。第三,定期审计权限,重点检查DBA角色的持有者、PUBLIC上的对象授权、以及带ADMIN OPTION的传递权限。
-- 检查谁拥有DBA角色
SELECT grantee FROM dba_role_privs WHERE granted_role = 'DBA';
-- 检查PUBLIC上的可疑授权
SELECT * FROM dba_tab_privs WHERE grantee = 'PUBLIC'
AND owner NOT IN ('SYS','SYSTEM');
-- 删除用户及其所有对象(危险操作,需谨慎)
DROP USER old_user CASCADE;第四,删除用户前先用SELECT * FROM dba_objects WHERE owner = 'OLD_USER';确认该用户名下有哪些对象,CASCADE会连人带对象一起删,一旦执行不可恢复,务必在备份验证后再操作。把这套规范落地后,账号权限体系会清晰很多,出问题时也能快速定位到具体是哪个环节的授权出了岔子。
Oracle用户管理权限授权GRANT REVOKE修改时间:2026-09-11 17:42:37