Part01-基础概念与理论知识
1.1 应用上下文概念
风哥教程参考Oracle官方文档Security部分。Oracle应用上下文是一种会话级别的命名空间,用于存储和管理应用程序的安全相关信息。它允许应用程序在会话期间维护用户的身份信息、权限信息和其他上下文数据。更多视频教程www.fgedu.net.cn
1.2 应用上下文的类型
1. 用户定义的应用上下文:由用户创建和管理的上下文;2. 内置应用上下文:Oracle数据库提供的预定义上下文,如USERENV。
1.3 应用上下文的优势
1. 提供会话级别的安全信息存储;2. 支持细粒度的访问控制;3. 简化应用程序的安全管理;4. 提高性能,避免重复查询用户权限信息。
Part02-生产环境规划与建议
2.1 上下文命名规划
生产环境建议使用有意义的上下文名称,如APP_CTX、HR_CTX、FIN_CTX等,便于管理和维护。上下文名称应该反映应用程序的功能或模块。
2.2 上下文属性规划
根据业务需求,规划上下文的属性,如USER_ID、USER_ROLE、DEPARTMENT、REGION等。属性名称应该简洁明了,反映属性的含义。
2.3 权限规划
规划谁可以创建、修改和使用应用上下文。通常,只有数据库管理员和应用程序所有者可以创建和管理应用上下文。
Part03-生产环境项目实施方案
3.1 创建应用上下文
使用CREATE CONTEXT语句创建应用上下文。
$ sqlplus / as sysdba
# 创建应用上下文
SQL> CREATE CONTEXT fgedu_fgapp_ctx USING fgedu_ctx_pkg;Context created.
3.2 创建上下文管理包
创建用于管理应用上下文的PL/SQL包。
SQL> CREATE OR REPLACE PACKAGE fgedu_ctx_pkg IS
PROCEDURE set_context(p_user_id IN NUMBER, p_user_role IN VARCHAR2, p_department IN VARCHAR2);PROCEDURE clear_context;END fgedu_ctx_pkg;/Package created.
# 创建包体
SQL> CREATE OR REPLACE PACKAGE BODY fgedu_ctx_pkg IS
PROCEDURE set_context(p_user_id IN NUMBER, p_user_role IN VARCHAR2, p_department IN VARCHAR2) IS
BEGIN
DBMS_SESSION.SET_CONTEXT(‘FGEDU_APP_CTX’, ‘USER_ID’, p_user_id);DBMS_SESSION.SET_CONTEXT(‘FGEDU_APP_CTX’, ‘USER_ROLE’, p_user_role);DBMS_SESSION.SET_CONTEXT(‘FGEDU_APP_CTX’, ‘DEPARTMENT’, p_department);END set_context;PROCEDURE clear_context IS
BEGIN
DBMS_SESSION.CLEAR_CONTEXT(‘FGEDU_APP_CTX’);END clear_context;END fgedu_ctx_pkg;/Package body created.
3.3 创建测试用户和表
创建测试用户和表,用于演示应用上下文的使用。
SQL> CREATE USER fgedu_test IDENTIFIED BY test123;User created.
# 授予权限
SQL> GRANT CONNECT, RESOURCE TO fgedu_test;Grant succeeded.
# 授予执行上下文包的权限
SQL> GRANT EXECUTE ON fgedu_ctx_pkg TO fgedu_test;Grant succeeded.
# 创建部门表
SQL> CREATE TABLE fgedu.dept (
dept_id NUMBER PRIMARY KEY,
dept_name VARCHAR2(50),
manager_id NUMBER
);Table created.
# 创建员工表
SQL> CREATE TABLE fgedu.emp (
emp_id NUMBER PRIMARY KEY,
emp_name VARCHAR2(50),
dept_id NUMBER REFERENCES fgedu.dept(dept_id),
salary NUMBER
);Table created.
# 插入测试数据
SQL> INSERT INTO fgedu.dept VALUES (10, ‘销售部’, 100);SQL> INSERT INTO fgedu.dept VALUES (20, ‘财务部’, 200);SQL> INSERT INTO fgedu.dept VALUES (30, ‘技术部’, 300);1 row created.
1 row created.
1 row created.
SQL> INSERT INTO fgedu.emp VALUES (100, ‘风哥1号’, 10, 8000);SQL> INSERT INTO fgedu.emp VALUES (101, ‘风哥2号’, 10, 6000);SQL> INSERT INTO fgedu.emp VALUES (200, ‘风哥3号’, 20, 9000);SQL> INSERT INTO fgedu.emp VALUES (201, ‘赵六’, 20, 7000);SQL> INSERT INTO fgedu.emp VALUES (300, ‘钱七’, 30, 10000);SQL> INSERT INTO fgedu.emp VALUES (301, ‘孙八’, 30, 8500);1 row created.
1 row created.
1 row created.
1 row created.
1 row created.
1 row created.
SQL> COMMIT;Commit complete.
3.4 创建基于上下文的VPD策略
创建基于应用上下文的虚拟私有数据库(VPD)策略,实现细粒度的访问控制。
SQL> CREATE OR REPLACE FUNCTION fgedu_emp_vpd_policy(
schema_name IN VARCHAR2,
table_name IN VARCHAR2
) RETURN VARCHAR2 IS
v_dept VARCHAR2(10);BEGIN
— 从应用上下文中获取部门信息
v_dept := SYS_CONTEXT(‘FGEDU_APP_CTX’, ‘DEPARTMENT’);– 如果是管理员角色,可以查看所有数据
IF SYS_CONTEXT(‘FGEDU_APP_CTX’, ‘USER_ROLE’) = ‘ADMIN’ THEN
RETURN NULL;END IF;– 否则只能查看自己部门的数据
RETURN ‘dept_id = ‘ || v_dept;END fgedu_emp_vpd_policy;/Function created.
# 启用VPD策略
SQL> EXEC DBMS_RLS.ADD_POLICY(
object_schema => ‘FGEDU’,
object_name => ‘EMP’,
policy_name => ‘EMP_DEPT_POLICY’,
function_schema => ‘SYS’,
policy_function => ‘fgedu_emp_vpd_policy’,
statement_types => ‘SELECT, INSERT, UPDATE, DELETE’
);PL/SQL procedure successfully completed.
Part04-生产案例与实战讲解
4.1 设置和使用应用上下文
设置应用上下文并验证其使用。
SQL> EXEC fgedu_ctx_pkg.set_context(100, ‘MANAGER’, ’10’);PL/SQL procedure successfully completed.
# 查看应用上下文
SQL> SELECT SYS_CONTEXT(‘FGEDU_APP_CTX’, ‘USER_ID’) AS user_id,
SYS_CONTEXT(‘FGEDU_APP_CTX’, ‘USER_ROLE’) AS user_role,
SYS_CONTEXT(‘FGEDU_APP_CTX’, ‘DEPARTMENT’) AS department
FROM dual;USER_ID USER_ROLE DEPARTMENT
———- ———- ———-
100 MANAGER 10
# 切换到测试用户
SQL> CONNECT fgedu_test/test123@fgedudb
Connected.
# 测试用户无法直接设置上下文(权限不足)
SQL> EXEC sys.fgedu_ctx_pkg.set_context(101, ‘EMPLOYEE’, ’10’);BEGIN sys.fgedu_ctx_pkg.set_context(101, ‘EMPLOYEE’, ’10’); END;*
ERROR at line 1:
ORA-01031: insufficient privileges
ORA-06512: at “SYS.FGEDU_CTX_PKG”, line 4
ORA-06512: at line 1
# 切换回sys用户,授予权限
SQL> CONNECT / as sysdba
Connected.
SQL> GRANT EXECUTE ON DBMS_SESSION TO fgedu_ctx_pkg;Grant succeeded.
# 创建存储过程,允许测试用户设置上下文
SQL> CREATE PROCEDURE fgedu.set_user_context(p_user_id NUMBER, p_user_role VARCHAR2, p_department VARCHAR2)
IS
BEGIN
fgedu_ctx_pkg.set_context(p_user_id, p_user_role, p_department);END;/Procedure created.
SQL> GRANT EXECUTE ON fgedu.set_user_context TO fgedu_test;Grant succeeded.
4.2 测试基于上下文的VPD策略
测试基于应用上下文的VPD策略是否生效。
SQL> CONNECT fgedu_test/test123@fgedudb
Connected.
# 设置上下文为销售部员工
SQL> EXEC fgedu.set_user_context(101, ‘EMPLOYEE’, ’10’);PL/SQL procedure successfully completed.
# 查询员工表,只能看到销售部的数据
SQL> SELECT * FROM fgedu.emp;EMP_ID EMP_NAME DEPT_ID SALARY
———- ————————————————– ———- ———-
100 风哥1号 10 8000
101 风哥2号 10 6000
# 设置上下文为财务部员工
SQL> EXEC fgedu.set_user_context(201, ‘EMPLOYEE’, ’20’);PL/SQL procedure successfully completed.
# 查询员工表,只能看到财务部的数据
SQL> SELECT * FROM fgedu.emp;EMP_ID EMP_NAME DEPT_ID SALARY
———- ————————————————– ———- ———-
200 风哥3号 20 9000
201 赵六 20 7000
# 设置上下文为管理员
SQL> EXEC fgedu.set_user_context(0, ‘ADMIN’, ‘0’);PL/SQL procedure successfully completed.
# 查询员工表,可以看到所有数据
SQL> SELECT * FROM fgedu.emp;EMP_ID EMP_NAME DEPT_ID SALARY
———- ————————————————– ———- ———-
100 风哥1号 10 8000
101 风哥2号 10 6000
200 风哥3号 20 9000
201 赵六 20 7000
300 钱七 30 10000
301 孙八 30 8500
4.3 使用内置上下文USERENV
使用Oracle内置的USERENV上下文获取会话信息。学习交流加群风哥QQ113257174
SQL> SELECT
SYS_CONTEXT(‘USERENV’, ‘SESSION_USER’) AS session_user,
SYS_CONTEXT(‘USERENV’, ‘CURRENT_USER’) AS current_user,
SYS_CONTEXT(‘USERENV’, ‘DB_NAME’) AS db_name,
SYS_CONTEXT(‘USERENV’, ‘HOST’) AS host,
SYS_CONTEXT(‘USERENV’, ‘IP_ADDRESS’) AS ip_address,
SYS_CONTEXT(‘USERENV’, ‘OS_USER’) AS os_user,
SYS_CONTEXT(‘USERENV’, ‘LANGUAGE’) AS language
FROM dual;SESSION_USER CURRENT_USER DB_NAME HOST IP_ADDRESS OS_USER LANGUAGE
—————————— —————————— ———— ——————————
———— ———— —————————————-
FGEDU_TEST FGEDU_TEST FGEDUDB db.fgedu.net.cn 192.168.1.100 oracle AMERICAN_AMERICA.AL32UTF8
4.4 创建登录触发器自动设置上下文
创建登录触发器,在用户登录时自动设置应用上下文。
SQL> CONNECT / as sysdba
Connected.
# 创建登录触发器
SQL> CREATE OR REPLACE TRIGGER fgedu_after_logon_trigger
AFTER LOGON ON DATABASE
DECLARE
v_user_id NUMBER;v_user_role VARCHAR2(20);v_dept_id NUMBER;BEGIN
— 只对特定用户设置上下文
IF USER IN (‘FGEDU_TEST’) THEN
— 根据用户名获取用户信息(这里简化处理,实际应从用户表查询)
IF USER = ‘FGEDU_TEST’ THEN
v_user_id := 101;v_user_role := ‘EMPLOYEE’;v_dept_id := 10;END IF;– 设置应用上下文
fgedu_ctx_pkg.set_context(v_user_id, v_user_role, v_dept_id);END IF;END;/Trigger created.
# 测试登录触发器
SQL> CONNECT fgedu_test/test123@fgedudb
Connected.
# 查看自动设置的上下文
SQL> SELECT SYS_CONTEXT(‘FGEDU_APP_CTX’, ‘USER_ID’) AS user_id,
SYS_CONTEXT(‘FGEDU_APP_CTX’, ‘USER_ROLE’) AS user_role,
SYS_CONTEXT(‘FGEDU_APP_CTX’, ‘DEPARTMENT’) AS department
FROM dual;USER_ID USER_ROLE DEPARTMENT
———- ———- ———-
101 EMPLOYEE 10
# 查询员工表,验证VPD策略生效
SQL> SELECT * FROM fgedu.emp;EMP_ID EMP_NAME DEPT_ID SALARY
———- ————————————————– ———- ———-
100 风哥1号 10 8000
101 风哥2号 10 6000
4.5 清除应用上下文
清除应用上下文中的属性或整个上下文。
SQL> EXEC DBMS_SESSION.CLEAR_CONTEXT(‘FGEDU_APP_CTX’, ‘USER_ROLE’);PL/SQL procedure successfully completed.
# 查看上下文,USER_ROLE属性已清除
SQL> SELECT SYS_CONTEXT(‘FGEDU_APP_CTX’, ‘USER_ID’) AS user_id,
SYS_CONTEXT(‘FGEDU_APP_CTX’, ‘USER_ROLE’) AS user_role,
SYS_CONTEXT(‘FGEDU_APP_CTX’, ‘DEPARTMENT’) AS department
FROM dual;USER_ID USER_ROLE DEPARTMENT
———- ———- ———-
101 10
# 清除整个上下文
SQL> EXEC fgedu_ctx_pkg.clear_context;PL/SQL procedure successfully completed.
# 查看上下文,所有属性已清除
SQL> SELECT SYS_CONTEXT(‘FGEDU_APP_CTX’, ‘USER_ID’) AS user_id,
SYS_CONTEXT(‘FGEDU_APP_CTX’, ‘USER_ROLE’) AS user_role,
SYS_CONTEXT(‘FGEDU_APP_CTX’, ‘DEPARTMENT’) AS department
FROM dual;USER_ID USER_ROLE DEPARTMENT
———- ———- ———-
Part05-风哥经验总结与分享
1. 应用上下文是Oracle数据库中强大的安全特性,用于存储和管理会话级别的安全信息。风哥提示:生产环境建议使用应用上下文结合VPD实现细粒度的访问控制。
2. 应用上下文可以简化应用程序的安全管理,避免在多个地方重复存储和验证用户信息。
3. 使用登录触发器可以自动设置应用上下文,提高用户体验和系统安全性。
4. 内置的USERENV上下文提供了丰富的会话信息,可以用于审计和监控。更多学习教程公众号风哥教程itpux_com
5. 定期审查应用上下文的使用情况,确保只存储必要的信息,避免安全风险。
6. 结合Oracle的其他安全特性,如角色、权限和审计,可以构建全面的安全体系。from oracle:www.itpux.com
学习交流加群风哥微信: itpux-com
