oracle应用用户需用create user按最小权限原则创建,显式设quota、强密码及专用profile;仅授create session等必要权限,禁用resource/dba角色;跨schema访问用同义词+definer's rights+显式授权;严查数据字典视图、db link、审计日志等隔离盲区。
oracle中创建应用专用用户的基本命令
直接用 create user 配合最小权限原则建用户,是隔离的第一步。别用 system 或 sys 直接跑应用逻辑——它们权限太大,出问题就是全库震荡。
典型操作如下:
CREATE USER app_finance IDENTIFIED BY "StrongPass123!" DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp QUOTA 100M ON users;
-
QUOTA必须显式设,否则新用户连建表都报ORA-01950: no privileges on tablespace 'USERS' - 密码里别用纯数字或常见单词,Oracle 12c+ 默认启用密码复杂度校验,
ALTER PROFILE DEFAULT LIMIT PASSWORD_VERIFY_FUNCTION ora12c_strong_verify_function这类配置可能已生效 - 不指定
PROFILE时默认走DEFAULT,但生产环境建议单独建 profile 控制失败登录次数、密码有效期等
给应用用户授什么权限才够用又安全
只给 CONNECT 和 RESOURCE 是历史遗留坑。这两个角色包含大量冗余权限(比如 RESOURCE 自带 UNLIMITED TABLESPACE),实际只需按需授权。
推荐组合:
- 基础连接:
CREATE SESSION - 建对象:
CREATE TABLE、CREATE VIEW、CREATE SEQUENCE(按应用需要选) - 执行自身对象:
ALTER ANY PROCEDURE换成ALTER PROCEDURE(仅对自己 schema 内的) - 绝对不要授
DBA、EXP_FULL_DATABASE、IMP_FULL_DATABASE这类高危角色
示例:
GRANT CREATE SESSION, CREATE TABLE, CREATE VIEW, CREATE SEQUENCE TO app_finance; GRANT SELECT, INSERT, UPDATE, DELETE ON app_finance.accounts TO app_finance;
注意:第二行是把本 schema 内表的 DML 权限回授给自己,否则存储过程里无法操作自己的表(Oracle 默认不隐式授予)。
同义词 + 定义者权限解决跨应用数据访问
当财务系统要查订单状态(订单在 app_order schema),又不想暴露对方表结构或账号密码,靠 SYNONYM + DEFINER'S RIGHTS 存储过程最稳妥。
- 在
app_finance下建同义词:CREATE SYNONYM order_status FOR app_order.orders; - 但直接
SELECT * FROM order_status会报ORA-00942: table or view does not exist—— 因为同义词只是别名,权限仍需显式授予 - 正确做法:由
app_order用户执行GRANT SELECT ON orders TO app_finance; - 若逻辑封装在存储过程中,确保该过程用
AUTHID DEFINER(默认),这样执行时以定义者(app_order)身份检查权限,调用者(app_finance)无需直接查表
容易被忽略的隔离盲区
用户、权限、同义词都配好了,依然可能被绕过隔离——关键在底层机制没关严。
-
DBA_USERS、DBA_TABLES等数据字典视图默认对所有有SELECT_CATALOG_ROLE的用户开放,而CONNECT角色在旧版本中自带这个权限。务必检查:SELECT * FROM DBA_ROLE_PRIVS WHERE GRANTEE = 'APP_FINANCE'; - 数据库链接(
DB LINK)是隔离漏洞高发区。一个应用用户若被授予了到其他库的 link,可能通过SELECT * FROM table@remote_db跳出当前库约束 - 审计日志本身也需隔离:
AUDIT SELECT ON app_finance.transactions BY ACCESS;只审计本应用关键表,避免日志爆炸,也防止审计结果被其他应用用户读取(UNIFIED_AUDIT_TRAIL视图需控制访问权限)
真正安全的隔离不是靠“建几个用户”,而是每层权限链都经得起反向推演:从连接进来,到能执行什么语句,再到能触达哪些数据块,中间不能有任何未声明的隐式通道。










