外观
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 19c | Oracle 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:可以使用以下方法:
- 检查具有DBA、SELECT ANY TABLE等高风险权限的用户
- 比较用户实际使用的权限与已授予的权限
- 使用Oracle 21c的权限分析工具识别过度授权
- 定期审查权限变更历史
- 对敏感操作实施审计,监控权限使用情况
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:可以通过以下方式实现:
- 建立定期权限审查机制(如每季度)
- 使用脚本生成权限报告,对比上次审查结果
- 对高风险权限实施定期轮换
- 结合统一审计,分析权限实际使用情况
- 使用Oracle Enterprise Manager自动化权限审查流程
总结
RBAC是Oracle数据库安全管理的核心框架,掌握其设计和实现对于DBA至关重要。通过合理规划用户、角色和权限,遵循最小权限原则,定期进行权限审计,可以有效保障数据库的安全性和合规性。
随着Oracle版本的演进,RBAC功能不断增强,特别是Oracle 21c提供了更强大的权限管理工具和更细粒度的控制能力。DBA应持续关注版本新特性,结合实际业务需求,不断优化权限管理策略,确保数据库在安全的同时保持良好的可用性。
