最近,人们对于理解和实现关系数据库中的低层访问控制,表示了浓厚的兴趣,尤其是对列或行级上的访问控制。本文将讲解该主题中的某些问题,并描述如何成功地实现对 DB2 Universal Database(DB2 UDB)的低层访问控制。
在电子商务的世界里,这些假设都不再适用。数据库中的信息访问正向第三方应用程序以及其 SQL 内容随用户需求和上下文变化的应用程序开放。这意味着,为了确保将规则有效地应用于所有访问数据库的用户和应用程序而不管使用的是什么应用程序,必须将实施低层访问控制的责任推给数据库。这种改变还有利于访问控制策略的集中编码,因为这些策略都是由信息存储的数据库中的信息属主来实现并维护的。
DB2 UDB 提供了种类繁多的机制,能用以根据用户不同的访问企图,实施相应的访问控制策略。这些机制包括表权限、列权限、视图和触发器。结合用户自定义的访问策略,可通过这些工具在 DB2 UDB 数据库中实现普遍的低层访问控制。
虽然此论述适用于所有平台(包括 390 和 400),但下面的具体例子是在 DB2 UDB 的 Unix、Windows 和 OS/2 版上执行的。
定义访问控制策略
来看如何实现低层安全的具体例子之前,我们必须回顾访问控制策略中需要定义什么。基本上,我们可以将该问题分为两部分:读访问控制和写访问控制。读访问控制特别与 SELECT 语句相关,而写访问控制则与 INSERT、UPDATE 和 DELETE 语句相关。为了成功地实现和维护一个访问策略,首先要对它进行清晰的定义。对于每行的读/写访问控制策略,需要回答以下问题:
一旦清晰地定义了这些元素,行和列级上的安全的访问控制策略就可以实现。例如,如果某公司有一张表,包含了所有雇员的信息,那么,该 employee 表的访问控制策略可能就是这个样子:
行访问策略
公共访问 | 雇员访问 | 人力资源访问 | 管理访问 |
Read: No rows Write: No rows |
Read: Own row Write: Own row Update |
Read: All rows Write: All rows Update Insert Delete |
Read: All row Write: All rows Update |
列访问策略
列内容 | 公共访问 | 雇员访问 | 人力资源访问 | 管理访问 |
Employee Identification Number | Read: No Write: No |
Read: Yes Write: No |
Read: Yes Write: No |
Read: Yes Write: No |
Employee User ID | Read: No Write: No |
Read: Yes Write: No |
Read: Yes Write: No |
Read: Yes Write: No |
Employee Information | Read: No Write: No |
Read: Yes Write: Update |
Read: Yes Write: Update |
Read: Yes Write: No |
Employee Evaluation | Read: No Write: No |
Read: No Write: No |
Read: Employee rows only Write: No |
Read: Yes Write: Update |
Department Number | Read: No Write: No |
Read: Yes Write: No |
Read: Yes Write: Update |
Read: Yes Write: No |
该策略为确定允许谁对哪些行或列执行何种操作奠定了基础。要实现该策略,我们还需要一个简洁的定义,以根据将实现该表的数据库的上下文来标识雇员,人力资源部的成员或管理小组的成员。在本例中,我们可以使用以下定义:
雇员
•将 | 其数据库用户 ID 出现在该表的 Employee Userid列中的用户定义为公司的雇员。 |
人力资源
• | d789 部门的雇员为人力资源(Human Resources,HR)部成员;该部门被视作雇员信息表的业务属主。该部门的成员定义为 ‘d789’ 组的仅有成员。 |
管理
• | d666 部门的雇员为管理(Management)小组的成员。将该部门成员定义为 ‘d666’ 组的仅有成员。 |
实现访问控制策略
一旦创建并验证了访问策略,我们就需要在目标数据库上安全地实现它。正如前面提到的,我们可以使用的工具和方法有很多,而且总是可以通过不同的方法来取得相同的结果。其指导原则就是,要使实现维护和实施起来尽可能简单。易理解的实现同样也易于审计和维护。
实现读访问策略
大多数访问策略的读部分最好是通过明智的授权以及使用视图作为到用户的外部接口来实现。第一道防线就是控制何人对主题表有 SELECT 权限。如果用户没有表上的该权限,他/她就不能访问表中的数据。通过最小化该权限的授予,以及将授权的能力只授予自身,您可以最小化访问暴露。
DB2 对动态的和静态的 SQL 语句均提供支持。静态 SQL 语句存储在系统目录表中,而该系统目录表处于一个称作 包的有组织的集合中。创建包时,DB2 检查执行该创建操作的用户 ID 是否拥有每个静态 SQL 语句所必需的权限。而将该用户 ID 称作 包授权 ID或包的 绑定者(binder)。要创建包,只需将直接访问表的权限显式地授予包的绑定者。一旦创建完成,其他用户就可以执行包中的静态 SQL 语句,只要他们拥有对包本身的 EXECUTE 权限,而无需拥有那些语句所必需的权限。但也请注意要严格控制对表操作的语句,因为它们也被定义为包的一部分。
对于动态 SQL 语句,DB2 检查企图执行该语句的用户 ID,或检查此 ID 所属的组是否拥有每个动态 SQL 语句所必需的权限。若应用程序被广泛使用,该工作将会十分繁重,因为每个用户要么必须被授予相同的权限,要么必须属于已授权的同一组。既限制对表的访问又不失动态 SQL 语句提供的灵活性的方法就是,在创建由应用程序使用的包时,使用 DYNAMICRULES(BIND) 选项。该选项表示将包授权 ID 用作包中所执行的动态 SQL 的授权 ID。这样做能简化事情是因为,与静态 SQL 语句采用的方式一样,只需要用创建包所使用的授权 ID 来获得表上的授权。
将视图作为首要工具来实现读访问策略是有利的,因为可以构造视图来隐藏行和/或列的存在,以及修改列的内容。视图的存在还允许通过它来解决主题表上访问权限的焦点问题;而用户只需被授予视图上的而非主题表本身上的 SELECT 权限。
|
一旦定义了这些基本表,通过使用视图和授予 SELECT 权限,我们就可以实现之前为雇员信息表定义的读访问策略了。本例中,我们可以使用两个视图定义:一个允许雇员查看他们自己的行,另一个则允许管理部门和人力资源(HR)部门的成员查看 employee 表中的全部行。
|
如下面的例子所示,基于使用不同的视图及其用户信息,我们将得到不同的结果。请注意 mgmt_access视图没有隐藏 employee_evaluation部门的成员查看一个管理人员的行时,该视图就隐藏了,或者说屏蔽了该列的值。我们还确保没有人可以越过各个视图上的授权设置:没有人可以对基本表执行 select 访问;只有 ‘d789’ 和 ‘d666’ 组的成员可以对 mgmt_access视图执行 select 访问,但所有人都可以访问 employee_access视图。本例假设使用动态 SQL 来访问多个表,所以与组授权相关。在静态 SQL 授权模式中,不能对任何组授权,只对指定的用于绑定包含了 SQL 的包的授权 ID 授权。通过对每个包使用一个不同的授权 ID,可以取得类似于静态 SQL 的权限判别。例如,一个包含了静态 SQL 的包可被所有雇员使用,并且可将对 employee_access视图的访问限于拥有其 SELECT 权限的某个授权 ID,那么,该包上的 EXECUTE 权限就可授予 PUBLIC。通过该方法,没有雇员可以访问表和视图,他们只能通过包中的静态 SQL 来获取信息。
— 由非 HR 部门的雇员(PBIRD)对 employee 表所作的选择(无访问权限) — 由管理部门的雇员(HUGO)对 employee 表所作的选择(无访问权限) — 由非 HR 部门的雇员(PBIRD)对 employee_access 视图所作的选择 |
— 由管理部门的雇员(HUGO)对 employee_access 视图所作的选择 — 由非 HR 部门的雇员(PBIRD)对 mgmt_access 视图所作的选择(无访问权限) — 由 HR 部门的雇员(MARY)对 mgmt_access 视图所作的选择(隐藏了 management evaluations) EMPLOYEE_ID USER_ID EMPLOYEE EVALUATION |
— 由管理部门对 mgmt_access 视图所作的选择(显示所有 evaluations) EMPLOYEE_ID USER_ID EMPLOYEE EVALUATION |
评论 {{userinfo.comments}}
{{child.content}}
{{question.question}}
提交