未记录事实核验 · 状态:维护中
记录仅说明核验时间与维护状态,不保证适用于所有环境;使用前请留意正文中的版本、适用条件与风险提示。
warning 适用边界与维护说明
本文适合学习Oracle用户、角色、对象授权及银行场景审计设计,不是可顺序执行的部署脚本或合规证明。示例依赖未提供的表空间、PROFILE、验证函数、角色和业务对象,实施前须结合实际环境确定对象所属模式、执行身份、直接授权、审计模式及资源限制生效条件。已有整表或继承权限不会因列级UPDATE授权、脱敏视图而自动收窄;权限审查过程也未列出全部有效权限。告警流程存在建表顺序、主键生成及自动锁号控制缺陷,不能直接用于生产;文中的明文密码和阈值仅供示例。
Oracle用户权限管理
Oracle安全架构概述
Oracle数据库采用多层安全架构,通过用户、角色、权限的组合来确保数据安全。在银行等金融机构中,严格的权限管理是监管合规和数据保护的基础要求。
1. 安全模型组成
用户(User)
- 数据库访问的基本单位
- 每个用户拥有独立的模式(Schema)
- 通过密码或其他认证方式验证身份
角色(Role)
- 权限的集合
- 简化权限管理
- 支持角色嵌套
权限(Privilege)
- 系统权限:数据库级别操作权限
- 对象权限:特定对象的操作权限
用户管理
1. 用户创建和配置
-- 创建银行业务用户
CREATE USER bank_analyst
IDENTIFIED BY "ComplexPass123!"
DEFAULT TABLESPACE customer_data
TEMPORARY TABLESPACE temp
QUOTA 100M ON customer_data
QUOTA 50M ON transaction_data
PROFILE bank_user_profile;
-- 创建应用系统用户
CREATE USER bank_app_user
IDENTIFIED BY "AppUser2023#"
DEFAULT TABLESPACE bank_core_data
TEMPORARY TABLESPACE temp
QUOTA UNLIMITED ON bank_core_data
QUOTA UNLIMITED ON transaction_data
PROFILE app_user_profile;
-- 创建只读用户
CREATE USER bank_readonly
IDENTIFIED BY "ReadOnly123$"
DEFAULT TABLESPACE users
TEMPORARY TABLESPACE temp
QUOTA 0 ON SYSTEM -- 禁止在SYSTEM表空间创建对象
PROFILE readonly_profile;
-- 创建DBA管理用户
CREATE USER bank_dba
IDENTIFIED BY "DbaPass456&"
DEFAULT TABLESPACE users
TEMPORARY TABLESPACE temp
PROFILE dba_profile;
2. 用户密码策略
-- 创建银行用户密码配置文件
CREATE PROFILE bank_user_profile LIMIT
SESSIONS_PER_USER 3 -- 最大并发会话数
CPU_PER_SESSION UNLIMITED -- 会话CPU时间
CPU_PER_CALL 3000 -- 单次调用CPU时间(百分之一秒)
CONNECT_TIME 480 -- 连接时间限制(分钟)
IDLE_TIME 30 -- 空闲时间限制(分钟)
LOGICAL_READS_PER_SESSION UNLIMITED
LOGICAL_READS_PER_CALL 1000
PRIVATE_SGA UNLIMITED
COMPOSITE_LIMIT UNLIMITED
PASSWORD_LIFE_TIME 90 -- 密码有效期(天)
PASSWORD_GRACE_TIME 7 -- 密码宽限期(天)
PASSWORD_REUSE_TIME 365 -- 密码重用时间间隔(天)
PASSWORD_REUSE_MAX 5 -- 密码重用次数限制
FAILED_LOGIN_ATTEMPTS 3 -- 登录失败次数限制
PASSWORD_LOCK_TIME 1 -- 账户锁定时间(天)
PASSWORD_VERIFY_FUNCTION bank_password_verify; -- 密码复杂度验证函数
-- 只读用户配置文件
CREATE PROFILE readonly_profile LIMIT
SESSIONS_PER_USER 2
CPU_PER_SESSION 1800
CONNECT_TIME 240
IDLE_TIME 15
PASSWORD_LIFE_TIME 60
PASSWORD_GRACE_TIME 3
FAILED_LOGIN_ATTEMPTS 5
PASSWORD_LOCK_TIME 0.25; -- 6小时
-- DBA配置文件
CREATE PROFILE dba_profile LIMIT
SESSIONS_PER_USER 5
CPU_PER_SESSION UNLIMITED
CONNECT_TIME UNLIMITED
IDLE_TIME 60
PASSWORD_LIFE_TIME 30
PASSWORD_GRACE_TIME 3
FAILED_LOGIN_ATTEMPTS 5
PASSWORD_LOCK_TIME 1
PASSWORD_VERIFY_FUNCTION strong_password_verify;
3. 密码复杂度验证函数
-- 银行密码复杂度验证函数
CREATE OR REPLACE FUNCTION bank_password_verify(
username VARCHAR2,
password VARCHAR2,
old_password VARCHAR2
) RETURN BOOLEAN
AS
n BOOLEAN := FALSE;
m INTEGER := 0;
differ INTEGER := 0;
isdigit BOOLEAN := FALSE;
isalpha BOOLEAN := FALSE;
isupper BOOLEAN := FALSE;
islower BOOLEAN := FALSE;
isspecial BOOLEAN := FALSE;
digitarray VARCHAR2(20) := '0123456789';
upperarray VARCHAR2(26) := 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
lowerarray VARCHAR2(26) := 'abcdefghijklmnopqrstuvwxyz';
specialarray VARCHAR2(25) := '!"#$%&()``*+,-/:;<=>?_';
BEGIN
-- 检查密码长度
IF LENGTH(password) < 8 THEN
RAISE_APPLICATION_ERROR(-20001, '密码长度至少8位');
END IF;
-- 检查密码不能与用户名相同
IF UPPER(password) = UPPER(username) THEN
RAISE_APPLICATION_ERROR(-20002, '密码不能与用户名相同');
END IF;
-- 检查密码复杂度
FOR i IN 1..LENGTH(password) LOOP
IF INSTR(digitarray, SUBSTR(password, i, 1)) > 0 THEN
isdigit := TRUE;
ELSIF INSTR(upperarray, SUBSTR(password, i, 1)) > 0 THEN
isupper := TRUE;
ELSIF INSTR(lowerarray, SUBSTR(password, i, 1)) > 0 THEN
islower := TRUE;
ELSIF INSTR(specialarray, SUBSTR(password, i, 1)) > 0 THEN
isspecial := TRUE;
END IF;
END LOOP;
-- 至少包含3种字符类型
m := 0;
IF isdigit THEN m := m + 1; END IF;
IF isupper THEN m := m + 1; END IF;
IF islower THEN m := m + 1; END IF;
IF isspecial THEN m := m + 1; END IF;
IF m < 3 THEN
RAISE_APPLICATION_ERROR(-20003, '密码必须包含至少3种字符类型(大写字母、小写字母、数字、特殊字符)');
END IF;
-- 检查与旧密码的差异
IF old_password IS NOT NULL THEN
differ := ABS(LENGTH(password) - LENGTH(old_password));
FOR i IN 1..LEAST(LENGTH(password), LENGTH(old_password)) LOOP
IF SUBSTR(password, i, 1) != SUBSTR(old_password, i, 1) THEN
differ := differ + 1;
END IF;
END LOOP;
IF differ < 3 THEN
RAISE_APPLICATION_ERROR(-20004, '新密码与旧密码至少要有3个字符不同');
END IF;
END IF;
RETURN TRUE;
END bank_password_verify;
/
角色管理
1. 银行业务角色设计
-- 创建银行业务角色层次结构
-- 基础数据查询角色
CREATE ROLE bank_data_reader;
GRANT SELECT ON customer_info TO bank_data_reader;
GRANT SELECT ON account_info TO bank_data_reader;
GRANT SELECT ON product_catalog TO bank_data_reader;
-- 交易查询角色
CREATE ROLE bank_transaction_reader;
GRANT bank_data_reader TO bank_transaction_reader; -- 继承基础查询权限
GRANT SELECT ON transaction_log TO bank_transaction_reader;
GRANT SELECT ON transaction_detail TO bank_transaction_reader;
-- 客户服务角色
CREATE ROLE bank_customer_service;
GRANT bank_transaction_reader TO bank_customer_service;
GRANT SELECT, UPDATE ON customer_info TO bank_customer_service;
GRANT SELECT ON account_balance_view TO bank_customer_service;
GRANT EXECUTE ON pkg_customer_service TO bank_customer_service;
-- 业务操作员角色
CREATE ROLE bank_operator;
GRANT bank_customer_service TO bank_operator;
GRANT INSERT, UPDATE, DELETE ON transaction_log TO bank_operator;
GRANT EXECUTE ON pkg_transaction_process TO bank_operator;
GRANT EXECUTE ON pkg_account_management TO bank_operator;
-- 分析师角色
CREATE ROLE bank_analyst_role;
GRANT bank_transaction_reader TO bank_analyst_role;
GRANT SELECT ON risk_assessment TO bank_analyst_role;
GRANT SELECT ON customer_analysis_view TO bank_analyst_role;
GRANT EXECUTE ON pkg_risk_analysis TO bank_analyst_role;
GRANT EXECUTE ON pkg_report_generator TO bank_analyst_role;
-- 风控角色
CREATE ROLE bank_risk_manager;
GRANT bank_analyst_role TO bank_risk_manager;
GRANT SELECT, INSERT, UPDATE ON risk_alert TO bank_risk_manager;
GRANT SELECT, INSERT, UPDATE ON blacklist TO bank_risk_manager;
GRANT EXECUTE ON pkg_aml_monitoring TO bank_risk_manager;
-- 审计角色
CREATE ROLE bank_auditor;
GRANT SELECT ON audit_log TO bank_auditor;
GRANT SELECT ON user_access_log TO bank_auditor;
GRANT SELECT ON dba_audit_trail TO bank_auditor;
GRANT EXECUTE ON pkg_audit_report TO bank_auditor;
-- 管理员角色
CREATE ROLE bank_admin;
GRANT bank_risk_manager TO bank_admin;
GRANT CREATE SESSION TO bank_admin;
GRANT CREATE TABLE TO bank_admin;
GRANT CREATE PROCEDURE TO bank_admin;
GRANT CREATE VIEW TO bank_admin;
2. 应用系统专用角色
-- 核心银行系统角色
CREATE ROLE core_banking_app;
GRANT CONNECT TO core_banking_app;
GRANT bank_operator TO core_banking_app;
GRANT CREATE SESSION TO core_banking_app;
GRANT ALTER SESSION TO core_banking_app;
-- 网银系统角色
CREATE ROLE online_banking_app;
GRANT CONNECT TO online_banking_app;
GRANT bank_customer_service TO online_banking_app;
GRANT SELECT ON customer_login_log TO online_banking_app;
GRANT INSERT, UPDATE ON customer_login_log TO online_banking_app;
-- 手机银行角色
CREATE ROLE mobile_banking_app;
GRANT CONNECT TO mobile_banking_app;
GRANT bank_customer_service TO mobile_banking_app;
GRANT EXECUTE ON pkg_mobile_service TO mobile_banking_app;
-- 报表系统角色
CREATE ROLE reporting_app;
GRANT CONNECT TO reporting_app;
GRANT bank_analyst_role TO reporting_app;
GRANT SELECT ON all_tables TO reporting_app; -- 限制性的查询权限
-- ATM系统角色
CREATE ROLE atm_app;
GRANT CONNECT TO atm_app;
GRANT SELECT ON customer_info TO atm_app;
GRANT SELECT ON account_info TO atm_app;
GRANT INSERT ON transaction_log TO atm_app;
GRANT EXECUTE ON pkg_atm_service TO atm_app;
3. 角色权限分配
-- 将角色分配给用户
GRANT bank_analyst_role TO bank_analyst;
GRANT core_banking_app TO bank_app_user;
GRANT bank_data_reader TO bank_readonly;
GRANT DBA TO bank_dba;
-- 设置默认角色
ALTER USER bank_analyst DEFAULT ROLE bank_analyst_role;
ALTER USER bank_app_user DEFAULT ROLE core_banking_app;
ALTER USER bank_readonly DEFAULT ROLE bank_data_reader;
-- 查看用户角色分配
SELECT
grantee,
granted_role,
admin_option,
default_role
FROM dba_role_privs
WHERE grantee IN ('BANK_ANALYST', 'BANK_APP_USER', 'BANK_READONLY')
ORDER BY grantee, granted_role;
权限管理
1. 系统权限管理
-- 查看系统权限
SELECT * FROM system_privilege_map ORDER BY name;
-- 常用系统权限分配
GRANT CREATE SESSION TO bank_user_role;
GRANT CREATE TABLE TO bank_developer_role;
GRANT CREATE PROCEDURE TO bank_developer_role;
GRANT CREATE VIEW TO bank_developer_role;
GRANT CREATE SEQUENCE TO bank_developer_role;
GRANT CREATE SYNONYM TO bank_user_role;
-- 限制性权限分配
GRANT CREATE SESSION TO bank_readonly;
REVOKE CREATE TABLE FROM bank_readonly;
REVOKE DROP ANY TABLE FROM bank_readonly;
-- 查看用户系统权限
SELECT
grantee,
privilege,
admin_option
FROM dba_sys_privs
WHERE grantee = 'BANK_ANALYST'
ORDER BY privilege;
2. 对象权限管理
-- 精细化对象权限控制
-- 客户信息表权限
GRANT SELECT ON customer_info TO bank_data_reader;
GRANT SELECT, UPDATE (phone, email, address) ON customer_info TO bank_customer_service;
GRANT SELECT, INSERT, UPDATE, DELETE ON customer_info TO bank_operator;
-- 账户信息表权限
GRANT SELECT ON account_info TO bank_data_reader;
GRANT SELECT ON account_info TO bank_customer_service;
GRANT SELECT, UPDATE (status, balance) ON account_info TO bank_operator;
-- 交易表权限
GRANT SELECT ON transaction_log TO bank_transaction_reader;
GRANT INSERT ON transaction_log TO bank_operator;
GRANT ALL ON transaction_log TO bank_admin;
-- 视图权限
CREATE OR REPLACE VIEW customer_summary_view AS
SELECT
c.customer_id,
c.customer_name,
c.phone,
c.email,
COUNT(a.account_id) as account_count,
SUM(a.balance) as total_balance
FROM customer_info c
LEFT JOIN account_info a ON c.customer_id = a.customer_id
GROUP BY c.customer_id, c.customer_name, c.phone, c.email;
GRANT SELECT ON customer_summary_view TO bank_analyst_role;
GRANT SELECT ON customer_summary_view TO bank_customer_service;
-- 存储过程权限
GRANT EXECUTE ON pkg_customer_service TO bank_customer_service;
GRANT EXECUTE ON pkg_transaction_process TO bank_operator;
GRANT EXECUTE ON pkg_risk_analysis TO bank_risk_manager;
3. 列级权限控制
-- 创建敏感信息访问控制
-- 客户敏感信息列权限
-- Oracle不支持通过GRANT SELECT列清单限制查询列;应创建仅包含允许查询列的视图并授予该视图的SELECT,同时处理已有的直接、角色继承及PUBLIC整表访问权限。
GRANT UPDATE (phone, email, address) ON customer_info TO bank_customer_service;
-- 禁止访问身份证号码
-- Oracle不支持按列撤销SELECT;要禁止查询id_card,必须移除可访问该列的整表或其他对象权限路径,再通过受限视图提供所需查询权限。
-- 创建脱敏视图
CREATE OR REPLACE VIEW customer_masked_view AS
SELECT
customer_id,
customer_name,
SUBSTR(phone, 1, 3) || '****' || SUBSTR(phone, 8) as masked_phone,
REGEXP_REPLACE(email, '(.{1,3}).*(@.*)', '\1***\2') as masked_email,
SUBSTR(id_card, 1, 6) || '********' || SUBSTR(id_card, 15) as masked_id_card,
address,
create_time
FROM customer_info;
GRANT SELECT ON customer_masked_view TO bank_data_reader;
审计和监控
1. 启用数据库审计
-- 启用审计功能
ALTER SYSTEM SET audit_trail = 'DB, EXTENDED' SCOPE = SPFILE;
-- 重启数据库使设置生效
-- 审计登录活动
AUDIT SESSION;
AUDIT SESSION BY bank_app_user;
-- 审计特权操作
AUDIT ALTER ANY TABLE;
AUDIT DROP ANY TABLE;
AUDIT CREATE USER;
AUDIT ALTER USER;
AUDIT DROP USER;
AUDIT GRANT ANY PRIVILEGE;
-- 审计敏感表操作
AUDIT SELECT, INSERT, UPDATE, DELETE ON customer_info BY ACCESS;
AUDIT SELECT, INSERT, UPDATE, DELETE ON account_info BY ACCESS;
AUDIT INSERT, UPDATE, DELETE ON transaction_log BY ACCESS;
-- 审计失败的操作
AUDIT SESSION WHENEVER NOT SUCCESSFUL;
AUDIT SELECT TABLE WHENEVER NOT SUCCESSFUL;
2. 访问监控视图
-- 创建用户访问监控视图
CREATE OR REPLACE VIEW v_user_access_monitor AS
SELECT
username,
terminal,
timestamp,
action_name,
obj_name,
returncode,
CASE
WHEN returncode = 0 THEN '成功'
ELSE '失败'
END as status,
client_id,
os_username
FROM dba_audit_trail
WHERE timestamp >= SYSDATE - 7; -- 最近7天
-- 登录失败监控
CREATE OR REPLACE VIEW v_failed_logins AS
SELECT
username,
terminal,
timestamp,
returncode,
COUNT(*) OVER (PARTITION BY username, TRUNC(timestamp)) as daily_failures
FROM dba_audit_trail
WHERE action_name = 'LOGON'
AND returncode != 0
AND timestamp >= SYSDATE - 1
ORDER BY timestamp DESC;
-- 权限使用统计
CREATE OR REPLACE VIEW v_privilege_usage AS
SELECT
username,
obj_name,
action_name,
COUNT(*) as access_count,
MIN(timestamp) as first_access,
MAX(timestamp) as last_access
FROM dba_audit_trail
WHERE timestamp >= SYSDATE - 30
AND returncode = 0
GROUP BY username, obj_name, action_name
ORDER BY access_count DESC;
3. 自动化安全监控
-- 创建安全监控存储过程
CREATE OR REPLACE PROCEDURE monitor_security_events
AS
CURSOR c_suspicious_activities IS
-- 检测异常登录模式
SELECT username, COUNT(*) as login_count
FROM dba_audit_trail
WHERE action_name = 'LOGON'
AND timestamp >= SYSDATE - 1/24 -- 最近1小时
AND returncode = 0
GROUP BY username
HAVING COUNT(*) > 10; -- 1小时内登录超过10次
CURSOR c_failed_logins IS
-- 检测登录失败
SELECT username, COUNT(*) as failure_count
FROM dba_audit_trail
WHERE action_name = 'LOGON'
AND timestamp >= SYSDATE - 1/24 -- 最近1小时
AND returncode != 0
GROUP BY username
HAVING COUNT(*) > 5; -- 1小时内失败超过5次
v_alert_count NUMBER := 0;
v_error_message VARCHAR2(1000);
BEGIN
-- 检查异常登录
FOR login_rec IN c_suspicious_activities LOOP
INSERT INTO security_alert (
alert_time, alert_type, username, description
) VALUES (
SYSDATE, 'EXCESSIVE_LOGINS', login_rec.username,
'用户1小时内登录' || login_rec.login_count || '次'
);
v_alert_count := v_alert_count + 1;
END LOOP;
-- 检查登录失败
FOR failure_rec IN c_failed_logins LOOP
INSERT INTO security_alert (
alert_time, alert_type, username, description
) VALUES (
SYSDATE, 'LOGIN_FAILURES', failure_rec.username,
'用户1小时内登录失败' || failure_rec.failure_count || '次'
);
v_alert_count := v_alert_count + 1;
-- 如果失败次数过多,锁定用户
IF failure_rec.failure_count > 10 THEN
EXECUTE IMMEDIATE 'ALTER USER ' || failure_rec.username || ' ACCOUNT LOCK';
INSERT INTO security_alert (
alert_time, alert_type, username, description
) VALUES (
SYSDATE, 'USER_LOCKED', failure_rec.username,
'用户因多次登录失败被自动锁定'
);
END IF;
END LOOP;
COMMIT;
IF v_alert_count > 0 THEN
DBMS_OUTPUT.PUT_LINE('发现 ' || v_alert_count || ' 个安全告警');
END IF;
EXCEPTION
WHEN OTHERS THEN
v_error_message := SUBSTR('安全监控过程执行失败: ' || SQLERRM, 1, 1000);
ROLLBACK;
INSERT INTO security_alert (
alert_time, alert_type, username, description
) VALUES (
SYSDATE, 'MONITOR_ERROR', 'SYSTEM',
v_error_message
);
COMMIT;
END monitor_security_events;
/
-- 创建安全告警表
CREATE TABLE security_alert (
alert_id NUMBER PRIMARY KEY,
alert_time DATE,
alert_type VARCHAR2(50),
username VARCHAR2(128),
description VARCHAR2(1000),
handled CHAR(1) DEFAULT 'N'
);
-- 定期执行安全监控
-- 可以通过DBMS_SCHEDULER定期执行
BEGIN
DBMS_SCHEDULER.CREATE_JOB(
job_name => 'SECURITY_MONITOR_JOB',
job_type => 'PLSQL_BLOCK',
job_action => 'BEGIN monitor_security_events; END;',
start_date => SYSDATE,
repeat_interval => 'FREQ=HOURLY; INTERVAL=1',
enabled => TRUE,
comments => '每小时执行安全监控'
);
END;
/
最佳实践和建议
1. 权限最小化原则
-- 创建最小权限用户示例
CREATE USER bank_report_user
IDENTIFIED BY "ReportUser123!"
DEFAULT TABLESPACE users
TEMPORARY TABLESPACE temp
QUOTA 10M ON users;
-- 只授予必要的权限
GRANT CREATE SESSION TO bank_report_user;
GRANT SELECT ON customer_summary_view TO bank_report_user;
GRANT SELECT ON transaction_summary_view TO bank_report_user;
GRANT EXECUTE ON pkg_report_functions TO bank_report_user;
-- 定期审查权限
CREATE OR REPLACE PROCEDURE review_user_privileges(p_username VARCHAR2)
AS
BEGIN
DBMS_OUTPUT.PUT_LINE('用户 ' || p_username || ' 的权限审查报告');
DBMS_OUTPUT.PUT_LINE('=====================================');
-- 系统权限
DBMS_OUTPUT.PUT_LINE('系统权限:');
FOR priv_rec IN (
SELECT privilege FROM dba_sys_privs
WHERE grantee = p_username
) LOOP
DBMS_OUTPUT.PUT_LINE(' ' || priv_rec.privilege);
END LOOP;
-- 角色权限
DBMS_OUTPUT.PUT_LINE('角色权限:');
FOR role_rec IN (
SELECT granted_role FROM dba_role_privs
WHERE grantee = p_username
) LOOP
DBMS_OUTPUT.PUT_LINE(' ' || role_rec.granted_role);
END LOOP;
-- 对象权限
DBMS_OUTPUT.PUT_LINE('对象权限:');
FOR obj_rec IN (
SELECT privilege, table_name FROM dba_tab_privs
WHERE grantee = p_username
) LOOP
DBMS_OUTPUT.PUT_LINE(' ' || obj_rec.privilege || ' ON ' || obj_rec.table_name);
END LOOP;
END;
/
2. 密码安全管理
-- 强制密码更改
ALTER USER bank_analyst PASSWORD EXPIRE;
-- 解锁被锁定的用户
ALTER USER bank_analyst ACCOUNT UNLOCK;
-- 查看用户状态
SELECT
username,
account_status,
lock_date,
expiry_date,
profile
FROM dba_users
WHERE username LIKE 'BANK_%'
ORDER BY username;
-- 批量密码策略更新
BEGIN
FOR user_rec IN (
SELECT username FROM dba_users
WHERE username LIKE 'BANK_%'
AND profile != 'BANK_USER_PROFILE'
) LOOP
EXECUTE IMMEDIATE 'ALTER USER ' || user_rec.username ||
' PROFILE bank_user_profile';
DBMS_OUTPUT.PUT_LINE('用户 ' || user_rec.username || ' 密码策略已更新');
END LOOP;
END;
/
Oracle用户权限管理是确保银行数据安全的核心机制。合理的用户、角色、权限设计和审计监控有助于降低数据泄露和非授权访问风险;本文配置仅为银行场景示例,是否满足金融行业合规要求仍取决于适用监管规定、实际配置和其他配套控制。