Skip to content

Oracle 用户与权限管理(RBAC)

基于角色的访问控制(RBAC)是Oracle数据库安全管理的核心框架,通过将权限聚合为角色,再将角色分配给用户,实现了权限的集中管理和精细化控制。对于DBA而言,掌握RBAC不仅是保障数据库安全的基础,更是实现合规要求的关键。

RBAC核心概念

用户(User)

用户是数据库的基本访问单元,具有以下特点:

  • 唯一的登录标识,用于身份验证
  • 可以拥有和管理数据库对象(表、视图、存储过程等)
  • 可以被授予角色和直接权限
  • 在多租户环境中,分为CDB用户和PDB用户

角色(Role)

角色是权限的集合,用于简化权限管理:

  • 可以包含系统权限、对象权限和其他角色
  • 支持权限的批量分配和回收
  • Oracle提供预定义角色和自定义角色两种类型
  • 可以设置角色密码,增强安全性

权限(Privilege)

权限是执行特定操作的授权,分为两种类型:

  • 系统权限:允许执行特定的数据库操作,如CREATE TABLE、ALTER SYSTEM等
  • 对象权限:允许访问或修改特定对象,如SELECT、INSERT、UPDATE、DELETE等

用户管理

用户创建

本地用户创建

sql
-- 创建普通业务用户
CREATE USER app_user IDENTIFIED BY "StrongPass_2023"
DEFAULT TABLESPACE app_data
TEMPORARY TABLESPACE temp
QUOTA 100M ON app_data
QUOTA 50M ON temp
PROFILE app_profile;

-- 创建应用管理员用户
CREATE USER app_admin IDENTIFIED BY "AdminPass_2023"
DEFAULT TABLESPACE app_data
TEMPORARY TABLESPACE temp
QUOTA UNLIMITED ON app_data
PROFILE admin_profile;

-- 创建只读用户
CREATE USER readonly_user IDENTIFIED BY "ReadPass_2023"
DEFAULT TABLESPACE users
TEMPORARY TABLESPACE temp
QUOTA 0 ON users
PROFILE readonly_profile;

多租户环境用户创建

sql
-- CDB级用户创建(适用于12c及以上版本)
CREATE USER c##common_user IDENTIFIED BY "CommonPass_2023" CONTAINER=ALL;

-- PDB级用户创建
ALTER SESSION SET CONTAINER=pdb1;
CREATE USER pdb_user IDENTIFIED BY "PdbPass_2023" CONTAINER=CURRENT;

用户属性管理

密码管理

sql
-- 修改用户密码
ALTER USER app_user IDENTIFIED BY "NewStrongPass_2023";

-- 强制用户首次登录修改密码
ALTER USER new_user IDENTIFIED BY "TempPass_2023" PASSWORD EXPIRE;

-- 锁定/解锁用户
ALTER USER app_user ACCOUNT LOCK;
ALTER USER app_user ACCOUNT UNLOCK;

-- 锁定用户并设置解锁时间
ALTER USER app_user ACCOUNT LOCK UNTIL '2023-12-31 23:59:59';

表空间与配额管理

sql
-- 修改默认表空间
ALTER USER app_user DEFAULT TABLESPACE app_data_new;

-- 修改临时表空间
ALTER USER app_user TEMPORARY TABLESPACE temp_new;

-- 调整表空间配额
ALTER USER app_user QUOTA 500M ON app_data;
ALTER USER app_user QUOTA UNLIMITED ON app_index;
ALTER USER app_user QUOTA 0 ON users;

配置文件管理

sql
-- 创建自定义配置文件
CREATE PROFILE app_profile LIMIT
  PASSWORD_LIFE_TIME 90
  PASSWORD_GRACE_TIME 7
  PASSWORD_REUSE_MAX 5
  PASSWORD_REUSE_TIME 180
  FAILED_LOGIN_ATTEMPTS 5
  PASSWORD_LOCK_TIME 1/24 -- 1小时
  SESSIONS_PER_USER 5
  CPU_PER_SESSION 10000
  CONNECT_TIME 60;

-- 为用户分配配置文件
ALTER USER app_user PROFILE app_profile;

用户删除

sql
-- 删除无对象用户
DROP USER app_user;

-- 删除含对象的用户(级联删除)
DROP USER app_user CASCADE;

-- 在多租户环境中删除PDB用户
ALTER SESSION SET CONTAINER=pdb1;
DROP USER pdb_user CASCADE;

权限管理

系统权限

常用系统权限

权限名称功能描述风险级别
CREATE SESSION允许连接到数据库
CREATE TABLE允许在用户 schema 中创建表
CREATE VIEW允许在用户 schema 中创建视图
CREATE PROCEDURE允许在用户 schema 中创建存储过程
ALTER SYSTEM允许执行系统级操作
CREATE USER允许创建新用户
DROP ANY TABLE允许删除任何 schema 中的表
SELECT ANY TABLE允许查询任何 schema 中的表

授予系统权限

sql
-- 授予单个权限
GRANT CREATE SESSION TO app_user;

-- 授予多个权限
GRANT CREATE TABLE, CREATE VIEW, CREATE PROCEDURE TO app_developer;

-- 授予权限并允许转授
GRANT CREATE USER TO app_admin WITH ADMIN OPTION;

-- 在多租户环境中授予容器级权限
GRANT CREATE SESSION TO c##common_user CONTAINER=ALL;

回收系统权限

sql
-- 回收单个权限
REVOKE CREATE TABLE FROM app_user;

-- 回收多个权限
REVOKE CREATE VIEW, CREATE PROCEDURE FROM app_developer;

-- 注意:系统权限回收不会级联
REVOKE CREATE USER FROM app_admin;

对象权限

常用对象权限

权限名称适用对象功能描述
SELECT表、视图、物化视图允许查询对象数据
INSERT表、视图允许插入数据
UPDATE表、视图允许更新数据
DELETE表、视图允许删除数据
ALTER表、序列、索引等允许修改对象结构
EXECUTE存储过程、函数、包允许执行对象
REFERENCES允许创建外键约束

授予对象权限

sql
-- 授予表的基本权限
GRANT SELECT, INSERT, UPDATE ON app_schema.employees TO app_user;

-- 授予表的列级权限
GRANT UPDATE (salary, commission_pct) ON app_schema.employees TO hr_user;

-- 授予存储过程执行权限
GRANT EXECUTE ON app_schema.get_employee_details TO app_user;

-- 授予权限并允许转授
GRANT SELECT ON app_schema.employees TO app_user WITH GRANT OPTION;

-- 授予所有表的SELECT权限(谨慎使用)
GRANT SELECT ANY TABLE TO readonly_user;

回收对象权限

sql
-- 回收单个权限
REVOKE UPDATE ON app_schema.employees FROM app_user;

-- 回收多个权限
REVOKE SELECT, INSERT ON app_schema.employees FROM app_user;

-- 注意:对象权限回收会级联
REVOKE SELECT ON app_schema.employees FROM app_user;

角色管理

预定义角色

Oracle提供了多个预定义角色,简化了权限管理:

核心预定义角色

  • CONNECT:基本连接权限(仅包含CREATE SESSION)
  • RESOURCE:应用开发权限(12c后仅包含UNLIMITED TABLESPACE)
  • DBA:数据库管理员角色,拥有几乎所有系统权限
  • SELECT_CATALOG_ROLE:允许查询数据字典视图
  • EXECUTE_CATALOG_ROLE:允许执行系统存储过程
  • DELETE_CATALOG_ROLE:允许删除系统表记录(谨慎使用)

多租户环境预定义角色

  • PDB_DBA:PDB级管理员角色
  • CDB_DBA:CDB级管理员角色
  • LOCAL_DB_AUDIT_STAT_ROLE:审计相关角色

自定义角色

创建自定义角色

sql
-- 创建基本角色
CREATE ROLE app_readonly;

-- 创建带密码的角色
CREATE ROLE app_developer IDENTIFIED BY "DevRolePass_2023";

-- 创建外部认证角色
CREATE ROLE ext_app_role IDENTIFIED EXTERNALLY;

-- 在多租户环境中创建容器级角色
CREATE ROLE c##common_role CONTAINER=ALL;

为角色授予权限

sql
-- 授予系统权限
GRANT CREATE SESSION, CREATE TABLE TO app_developer;

-- 授予对象权限
GRANT SELECT, INSERT, UPDATE ON app_schema.employees TO app_user_role;
GRANT EXECUTE ON app_schema.get_employee_details TO app_user_role;

-- 授予其他角色
GRANT app_readonly TO app_developer;

-- 在多租户环境中授予权限
GRANT CREATE SESSION TO c##common_role CONTAINER=ALL;

角色授予与激活

sql
-- 将角色授予用户
GRANT app_readonly, app_user_role TO app_user;

-- 将带密码的角色授予用户
GRANT app_developer TO app_user IDENTIFIED BY "DevRolePass_2023";

-- 设置用户默认角色
ALTER USER app_user DEFAULT ROLE app_readonly, app_user_role;

-- 会话级别激活角色
SET ROLE app_developer IDENTIFIED BY "DevRolePass_2023";

-- 激活所有角色
SET ROLE ALL;

-- 激活所有角色除了特定角色
SET ROLE ALL EXCEPT app_developer;

角色修改与删除

sql
-- 修改角色密码
ALTER ROLE app_developer IDENTIFIED BY "NewDevRolePass_2023";

-- 禁用角色密码
ALTER ROLE app_developer NOT IDENTIFIED;

-- 删除角色
DROP ROLE app_obsolete_role;

-- 在多租户环境中删除容器级角色
DROP ROLE c##common_role CONTAINER=ALL;

Oracle 19c与21c RBAC差异

特性Oracle 19cOracle 21c
多租户权限管理支持基本的CDB/PDB权限分离增强的容器级权限,支持更细粒度控制
角色继承支持简单的角色层次增强的角色继承,支持复杂角色层次结构
临时角色不支持支持临时角色,会话结束后自动失效
权限分析工具基础的权限报告增强的权限分析,提供过度授权识别
密码策略基础密码规则支持增强的密码策略,支持更复杂的密码验证
统一审计集成基础集成深度集成统一审计,提供更全面的权限使用审计
最小权限建议内置最小权限建议功能,帮助优化权限配置
PDB级角色管理支持增强的PDB角色管理,支持跨PDB角色授予

生产环境最佳实践

1. 遵循最小权限原则

  • 只授予用户完成工作所需的最小权限
  • 避免直接授予系统权限,优先使用角色
  • 定期审查权限,及时回收不必要的授权
  • 对敏感数据(如财务、个人信息)实施严格的访问控制

2. 建立完善的角色体系

  • 按职能划分角色(如app_readonly、app_developer、app_admin)
  • 建立角色层次结构,实现权限的继承和精细化管理
  • 为每个应用创建独立的角色集,避免权限冲突
  • 定期审查角色权限,确保符合业务需求

3. 强化密码管理

  • 使用强密码策略,包括长度、复杂度、有效期
  • 启用密码历史记录,防止密码重复使用
  • 设置合理的失败登录尝试次数和锁定时间
  • 对管理员账号实施更严格的密码策略

4. 定期权限审计

sql
-- 检查具有DBA权限的用户
SELECT grantee FROM DBA_ROLE_PRIVS WHERE granted_role = 'DBA';

-- 检查具有SELECT ANY TABLE权限的用户
SELECT grantee FROM DBA_SYS_PRIVS WHERE privilege = 'SELECT ANY TABLE';

-- 检查用户的角色和权限
SELECT * FROM DBA_ROLE_PRIVS WHERE grantee = 'APP_USER';
SELECT * FROM DBA_SYS_PRIVS WHERE grantee = 'APP_USER';
SELECT * FROM DBA_TAB_PRIVS WHERE grantee = 'APP_USER';

-- 查找过度授权的用户
SELECT grantee, COUNT(*) AS privilege_count 
FROM DBA_SYS_PRIVS 
GROUP BY grantee 
HAVING COUNT(*) > 20;

5. 多租户环境权限管理

  • 严格区分CDB用户和PDB用户
  • 避免在CDB级别授予过多权限
  • 对每个PDB使用独立的角色体系
  • 定期检查CDB$ROOT中的公共权限

6. 使用统一审计

sql
-- 启用统一审计
ALTER SYSTEM SET audit_trail = DB, UNIFIED SCOPE=SPFILE;

-- 创建审计策略
CREATE AUDIT POLICY app_audit_policy
PRIVILEGES CREATE TABLE, ALTER TABLE, DROP TABLE,
SELECT ANY TABLE, INSERT ANY TABLE, UPDATE ANY TABLE, DELETE ANY TABLE
WHEN 'SYS_CONTEXT(''USERENV'',''SESSION_USER'') NOT IN (''SYS'',''SYSTEM'')' 
EVALUATE PER SESSION;

-- 启用审计策略
AUDIT POLICY app_audit_policy;

-- 查看审计记录
SELECT * FROM UNIFIED_AUDIT_TRAIL WHERE ACTION_NAME = 'SELECT' AND OBJECT_NAME = 'EMPLOYEES';

常见问题(FAQ)

Q:如何快速查看用户的所有权限?

A:可以使用以下SQL脚本生成用户权限报告:

sql
SET LINESIZE 200
SET PAGESIZE 1000

PROMPT ===========================
PROMPT User: &username
PROMPT ===========================

-- 角色权限
PROMPT 
PROMPT --- ROLE PRIVILEGES ---
SELECT granted_role, admin_option, default_role 
FROM DBA_ROLE_PRIVS 
WHERE grantee = UPPER('&username');

-- 系统权限
PROMPT 
PROMPT --- SYSTEM PRIVILEGES ---
SELECT privilege, admin_option 
FROM DBA_SYS_PRIVS 
WHERE grantee = UPPER('&username');

-- 对象权限
PROMPT 
PROMPT --- OBJECT PRIVILEGES ---
SELECT owner, table_name, privilege, grantable 
FROM DBA_TAB_PRIVS 
WHERE grantee = UPPER('&username');

Q:如何创建一个只能访问特定表的用户?

A:可以通过以下步骤实现:

sql
-- 1. 创建用户
CREATE USER restricted_user IDENTIFIED BY "RestrictPass_2023";

-- 2. 授予基本连接权限
GRANT CREATE SESSION TO restricted_user;

-- 3. 授予特定表的SELECT权限
GRANT SELECT ON app_schema.employees TO restricted_user;
GRANT SELECT ON app_schema.departments TO restricted_user;

-- 4. 可选:创建只读角色并授予
CREATE ROLE app_readonly_role;
GRANT SELECT ON app_schema.employees TO app_readonly_role;
GRANT SELECT ON app_schema.departments TO app_readonly_role;
GRANT app_readonly_role TO restricted_user;

Q:如何处理权限回收后的级联问题?

A:权限回收的级联行为取决于权限类型:

  • 系统权限:使用WITH ADMIN OPTION授予的系统权限,回收时不会级联回收被转授的权限
  • 对象权限:使用WITH GRANT OPTION授予的对象权限,回收时会级联回收被转授的权限
  • 角色:回收角色时,会级联回收被转授的角色

Q:Oracle 21c的临时角色如何使用?

A:临时角色在会话结束后自动失效,适合临时授予高权限:

sql
-- 创建临时角色
CREATE ROLE temp_admin_role TEMPORARY;

-- 授予权限
GRANT ALTER TABLE, DROP TABLE TO temp_admin_role;

-- 授予用户
GRANT temp_admin_role TO app_user;

-- 会话中激活
SET ROLE temp_admin_role;

-- 会话结束后,角色自动失效

Q:如何发现数据库中的过度授权?

A:可以使用以下方法:

  1. 检查具有DBA、SELECT ANY TABLE等高风险权限的用户
  2. 比较用户实际使用的权限与已授予的权限
  3. 使用Oracle 21c的权限分析工具识别过度授权
  4. 定期审查权限变更历史
  5. 对敏感操作实施审计,监控权限使用情况

Q:多租户环境中如何管理CDB和PDB权限?

A:遵循以下原则:

  • CDB用户主要用于管理PDB,避免授予业务权限
  • PDB用户用于业务访问,权限限制在PDB内
  • 使用CONTAINER=ALL子句管理容器级权限
  • 避免在CDB$ROOT中创建公共对象和权限
  • 定期检查CDB和PDB之间的权限泄漏

Q:如何撤销用户的所有权限?

A:可以使用以下步骤:

sql
-- 1. 查看用户的所有角色
SELECT granted_role FROM DBA_ROLE_PRIVS WHERE grantee = 'APP_USER';

-- 2. 撤销所有角色
REVOKE role1, role2, role3 FROM app_user;

-- 3. 查看用户的所有系统权限
SELECT privilege FROM DBA_SYS_PRIVS WHERE grantee = 'APP_USER';

-- 4. 撤销所有系统权限
REVOKE privilege1, privilege2 FROM app_user;

-- 5. 查看用户的所有对象权限
SELECT owner, table_name, privilege FROM DBA_TAB_PRIVS WHERE grantee = 'APP_USER';

-- 6. 撤销所有对象权限
REVOKE privilege1 ON object1 FROM app_user;
REVOKE privilege2 ON object2 FROM app_user;

Q:如何实现权限的定期审查和轮换?

A:可以通过以下方式实现:

  1. 建立定期权限审查机制(如每季度)
  2. 使用脚本生成权限报告,对比上次审查结果
  3. 对高风险权限实施定期轮换
  4. 结合统一审计,分析权限实际使用情况
  5. 使用Oracle Enterprise Manager自动化权限审查流程

总结

RBAC是Oracle数据库安全管理的核心框架,掌握其设计和实现对于DBA至关重要。通过合理规划用户、角色和权限,遵循最小权限原则,定期进行权限审计,可以有效保障数据库的安全性和合规性。

随着Oracle版本的演进,RBAC功能不断增强,特别是Oracle 21c提供了更强大的权限管理工具和更细粒度的控制能力。DBA应持续关注版本新特性,结合实际业务需求,不断优化权限管理策略,确保数据库在安全的同时保持良好的可用性。