ORACLE 精细访问控制的实现
一些与业务规则有关的安全需求是具体或精细的,不是仅仅直接靠授予什么系统权限或对象权限就能解决的,因为在这些访问控制中可能包含了某些逻辑判断,需要用程序的方式实现某些安全策略,做到对访问权限的精细控制。
创建一个VPD不是安装或配置一个Oracle软件工具或应用程序,而是需要分析数据库、创建环境和策略、编写函数和触发器、测试结果等技术活动。下面按次序、分步骤介绍这些内容。
1. 确定数据库对象以及它们之间的关系
在开始创建一个VPD之前,必须确定这个VPD所涉及的数据库对象(如表、视图)、它们之间的关系,以及where子句中可能使用的列。
例如,在部门和员工管理中涉及到的表及其关系(如图1)所 示。这2个表之间通过deptno列来建立参照完整性约束,一个部门中可以有多个员工。如果需要通过部门的名称dname来查询某个部门的员工信息的话, 就需要用到dept和emp两个表;如果只需要通过部门的编号deptno来查询某个部门的员工信息的话,就只需要使用emp表。
图1
2. 确定安全策略的目标
为了简单期间,某个安全策略的目标可以描述为:scott用户可以访问所有员工的信息,system用户可以访问部门10或20的员工的信息。
实际工作中的安全策略的目标往往比这个策略要复杂。还可能需要把几个安全策略(如使用select语句时的安全策略、使用update语句时的安全策略) 关联到一个表或视图上。因为这些安全策略的目标最后都必须被转换成为PL/SQL函数代码后,才能被DBMS_RLS包关联到一个表或视图上,所以安全策 略的目标应该是清晰明了的、可实现的,这样才好编写PL/SQL函数代码。
如果对PL/SQL程序设计不太熟悉,就需要学习相应的内容(如函数、触发器、包),或请这方面的专业的开发人员来帮助实现。至少要帮助实现第一个安全策略的目标。
3. 创建应用环境
一个应用环境实际上包含一组属性,可以给其中的某个属性设置相应的属性值,也可以读取某个属性属性值。例如,人这个环境有皮肤颜色、眼睛颜色这些属性,其中皮肤颜色可以取白色、黄色、黑色、棕色等值。
一、默认应用环境userenv
在创建数据库后,系统提供了一个默认的、名为userenv的应用环境。它包含了与当前会话相关联的系统信息,其中部分属性如下表所示。
userenv应用环境的部分属性
属性
说明
Authentication_type
验证用户的方式。可取的值是:
Database――用户名/密码身份验证法
Os――操作系统外部身份验证法
Network――网络协议或ANO身份验证法
Proxy――OCI代理身份验证法
Current_schema
当前会话所对应的方案名
Db_domain
初始化参数db_domain所设定的数据库域名
Db_name
初始化参数db_name所设定的数据库名
Host
数据库所在的主机名
Isdba
如果当前用户被授予过dba角色,则返回true,否则返回false
Network_protocol
本次连接所使用的通信协议
Os_user
本次会话的客户的操作系统用户名
Session_user
本次会话身份验证中给出的数据库用户名
Language
本次会话所使用的语言、地区和字符集
NLS_date_format
本次会话所使用的日期格式
二、读取应用环境的属性值
Oracle 提供了一个所有用户都可以使用的、名为sys_context的系统函数来读取应用环境(包括默认的、自定义的应用环境)的属性值。该函数的第1个参数是 应用环境的名称,第2个参数是要读取其值的属性的名称。一般用该函数来读取默认应用环境的属性值,以便了解当前会话的信息。
【例】查询当前会话的用户名、操作系统用户名、使用的日期格式、使用的语言,如(图2)所示。
图2 用sys_context系统函数、userenv应用环境来查询当前会话的信息
三、创建自定义应用环境
要创建自定义应用环境,必须要拥有create any context系统权限。
为了实现精细访问控制,必须创建自定义的应用环境,以便保存自定义的、与某个会话(即不同的用户)相关联的属性。创建自定义应用环境时需要给它取一个独一无二的、有意义的名字(图3)。
图3 创建(自定义)应用环境
执行上述命令后,会创建一个名为empenv的应用环境,其各个属性都由scott用户的、名为emp_ctx的包方案对象进行设置。创建应用环境时不需要包存在,可以在以后再创建它。
四、定义和设置应用环境的属性
在应用环境中定义和设置属性可以调用DBMS_SESSION.SET_CONTEXT过程,其语法是:
DBMS_SESSION.SET_CONTEXT('context_name', 'attribute_name', 'attribute_value');
例如,在一个名为empenv的应用环境中定义一个名为scott_attr1的属性,其取值为10的调用是:
DBMS_SESSION.SET_CONTEXT('empenv', 'scott_attr1', '10');
4. 创建包来设置应用环境的属性
一旦创建了自定义的应用环境,就要创建用于设置其中的属性的包。
可 以从默认的userenv应用环境中得到当前会话的用户名。假设本例子的安全策略的目标是,当会话用户是scott时,只访问部门10的员工的信息,所以 可以用一个名为scott_attr1的属性来保存10;当会话用户是system时,只访问部门10或20的员工的信息,所以可以用2个名为 system_attr1和system_attr2的属性来保存10和20。这个设置应用环境的属性的包的定义(如图4)。
图4 创建包来设置应用环境的属性
注 意:每个会话应该有自己的一套属性。不要在属性中写带有AND、OR、NOT的逻辑表达式。如果属性值是字符串,且其中还有空格,就要用单引号,否则不需要。
5. 创建安全策略函数接下来就是创建一个用来实现安全策略的PL/SQL函数(下一步会将这个函数关联到emp表上去)。这个安全策略函数必须带2个参数:第1个参数是方案名(或用户名)、第2个参数是方案对象名(或表名、视图名)。该函数返回附加到SQL语句的where子句后面的字符串如(图5)。
提 示:即使在安全策略函数中不使用也要带上所述2个参数,否则在执行时会出现“ORA-28112: 无法执行策略函数”的错误提示。
图5 创建安全策略函数
注 意:在返回的谓词中只能包含where子句后面的条件,不能有where关键字,也不能包含其他子句(如order by),否则在执行时会出现“ORA-28113: 策略谓语有错误”的错误提示。这些子句可以在使用SQL语句时添加。
从 图13.62中的安全策略函数可知,这里定义了2个函数:select_lmt()、update_lmt ()。其中select_lmt()的目的是用于对select进行访问控制,当是scott用户时,只允许其查询部门10的员工信息,当是system 用户时,只允许其查询部门10或部门20的员工信息,而对其他用户不做限制;update_lmt ()的目的是用于对update(包括insert、update、delete)进行访问控制,当是system用户时,只允许其更改部门20的员工信 息,而不允许其他用户做任何更改。
6. 将安全策略函数关联到表或视图上
Oracle为我们提供了一个名为DBMS_RLS(Row Level Security,行级安全)的PL/SQL包来进行安全策略的管理工作。这个包中有几个过程,其声明部分可以在%ORACLE_HOME%\RDBMS\ADMIN目录中找到,其部分内容(如图6)。要想使用DBMS_RLS包,必须是sys用户或必须从sys用户那里获得了执行这个包的execute对象权限。
“提 示”SQL语句中的where条件只是控制所操作的行的,所以起类似作用的DBMS_RLS包控制的就是行级安全。
图6 DBMS_RLS包及其过程ADD_POLICY的声明部分
如(图7)所 示,在scott方案的emp表上添加了2个安全策略:select_policy、update_policy。它们的安全策略函数来自scott方案 的emp_security.select_lmt、emp_security.update_lmt。select_policy安全策略针对的是 select语句,update_policy安全策略针对的是insert、update、delete语句。
图7.添加安全策略
一旦把安全策略函数关联到表或视图上,这些用户对这些表或视图的访问就会在精细访问控制之下。Oracle会把经过分析之后的语句放到共享池 (shared pool)中,这样一来,具有相同访问权限的、使用相同SQL语句的用户就可以使用这个分析之后的语句了。
7. 创建登录触发器
一切安排妥当之后,还需要创建一个触发器来激活安全策略(或调用安全策略函数)。建议使用登录(on logon)触发器来做这件事。其好处是,不管用户是采用什么方法连接到数据库,这个应用环境或安全策略都会被激活,如(图8)所示。
图8 创建登录触发器
注 意:必须是具有sysdba系统权限的用户(如sys用户、以sysdba连接身份)登录后创建登录触发器。如果登录触发器创建有错,可能会使相应的用户 无法登录数据库。果真如此的话,就应该以一位具有sysdba系统权限的用户登录数据库并禁用(ALTER TRIGGER trigger_name DISABLE)引起问题的登录触发器,然后进行更改,最后再启用(ALTER TRIGGER trigger_name ENABLE)登录触发器。
“提 示”如果要删除登录触发器,可以用(图9)所示的例子。
图9 删除登录触发器
8. 验证精细访问控制的效果
至此,已经实现了预定的精细访问控制。下面用几个示例来说明其效果。
【例】scott用户登录后,只能查询部门10的人员的信息,并不能更改任何部门、任何人员的信息,如(图10)所示。
图10 对scott用户的精细访问控制的效果
【例】system用户登录后,可以查询部门10或部门20的人员的信息,只能更改部门20的人员的信息,不能更改其他部门的任何人员的信息,如(图11)所示
图11对system用户的精细访问控制的效果
【例】如果以SYSDBA身份登录时,不会触发登录触发器,所以将不受安全策略函数的控制,如(图12)所示。
图12对SYSDBA用户的精细访问控制的效果
从 上面几个例子中的SQL语句可以看出,精细访问控制对用户是透明的,即,可以仍然按SQL语言的语法来编写语句。另外,也不能简单地将精细访问控制理解为 就是在原来的SQL语句后面再添加一条where子句。否则就无法理解system用户提交的UPDATE scott.emp SET sal = 5000 WHERE empno = 7788;
这条语句也能正确执行的语法结构了。更不能理解没有where子句的insert语句也能正确执行的语法结构了。
9. 查询当前用户的对象的安全策略
与对象的安全策略相关的数据字典视图如表13.7所示。
表13.7 与对象的安全策略相关的数据字典视图
|
视图 |
说明 |
|
DBA_POLICIES |
数据库中定义的所有对象的安全策略 |
|
ALL_POLICIES |
所有用户的对象的安全策略 |
|
USER_POLICIES |
当前用户的对象的安全策略 |
(图13)所示的例子显示了如何查询自己的所有对象的安全策略。
图13查询当前用户的对象的安全策略
从查询结果的第1行可知(由列名就可以知道所包含的信息),在emp表上有一个名为select_policy的安全策略,其安全策略函数select_lmt定义在包emp_security中,该安全策略是针对select语句的,并且当前处于启用状态。
10. 启用或禁用、删除对象的安全策略
DBMS_RLS包的ENABLE_POLICY过程可以使一个安全策略暂时无效而不必删除它。可以暂时禁用update_policy安全策略,如(图14)所示。enable参数是一个布尔值,取值为TRUE(启用)或FALSE(禁用)。
图14启用或禁用对象的安全策略
如果不再需要某个表或视图上的某个安全策略时,可以调用DBMS_RLS包的DROP_POLICY过程将其删除。可以删除select_policy安全策略,如(图15)所示。
图15删除对象的安全策略
至此,通过禁用、删除安全策略之后,scott用户的安全策略如(图16)所示。
图16 维护安全策略之后scott用户的安全策略
总结:
Oracle 数据库的权限分成系统权限、对象权限。系统权限在系统级控制对数据库的存取和操作,如,用户是否能通过建立会话而连接到数据库,是否能启动/关闭数据库, 是否能查询数据字典视图等。对象权限在方案级控制对数据库的存取和操作,如,用户可以存取哪个方案中的对象,是否能对该对象进行查询、插入、更新、删除 等。
只有具有相应权限的用户才能进行相应的操作。通过向用户授予或回收权限,就能控制用户在数据库中能做什么和不能做什么。所以,通过用户名和口令控制是否能登录数据库只是第一道防线,Oracle数据库的安全机制主要还是通过权限这第二道防线来进行控制的。
系 统权限一般是由具有sysoper、sysdba权限的DBA用户(即sys用户、system用户,他们具有数据库的所有系统权限)来授予的;对象权限 一般是由对象的拥有者(他具有该对象的所有对象权限)来授予的。如果在授予系统权限时使用了WITH ADMIN OPTION选项,那么获得该系统权限的用户还可以将该系统权限传递给其他用户;如果在授予对象权限时使用了WITH GRANT OPTION选项,那么获得该对象权限的用户还可以将该对象权限传递给其他用户。授予权限的基本语法是:GRANT……TO……。
一 个新创建的用户是一个有名无实的用户,如果不给他授予create session系统权限,他连数据库都不能登录。如果在表空间中没有配额,就算有了create table系统权限,也不能创建表。不同的对象上可以授予的对象权限是不同的。例如目录对象只有read对象权限,过程只有execute对象权限。
应 该按实际情况只给用户授予最少的权限或回收过大的权限,否则可能会使系统、使对象存在安全性隐患。因为在授予权限后,可能权限是可以传递的,所以回收权限 时要注意如何才能完全收回权限。回收系统权限时不会级联回收,而回收对象权限时会级联回收。回收权限的基本语法是:REVOKE……FROM……。
虚 拟专用数据库或精细访问控制,给我们提供了另外一种对权限进行控制的方案。这种方案能按不同的用户,制定出相应的安全策略。这些安全策略对用户而言是透明 的,不会影响其编写的SQL的语法。可以用PL/SQL函数来编写具有复杂逻辑的安全策略,实现用直接地、简单地授予系统权限或对象权限而无法实现的权限 管理。但最终安全策略的实现还是受到系统权限或对象权限控制。
与管理安全策略有关的PL/SQL包是DBMS_SESSION、DBMS_RLS。
hi.baidu.com/dba_james/blog/item/32f261ae32eb31fcfaed50b9.html
浙公网安备 33010602011771号