实现对 DB2 UDB 的低层访问控制

  • 来源: 互联网 作者: 若水   2008-03-19/15:18
  • 本文将讲解该主题中的某些问题,并描述如何成功地实现对 DB2 Universal Database(DB2 UDB)的低层访问控制。

    最近,人们对于理解和实现关系数据库中的低层访问控制,表示了浓厚的兴趣,尤其是对列或行级上的访问控制。本文将讲解该主题中的某些问题,并描述如何成功地实现对 DB2 Universal Database(DB2 UDB)的低层访问控制。

    低层访问控制是指,能按行或列来限制数据是否可见或能否被数据库用户修改。过去,在应用程序  中通过补充 SQL 语句的谓词,或通过检查返回的数据值以确定行或列是否应该包含在用户可见集合中,来完成该类控制。此方法存在一个较大的不足:它要求应用程序能够阻止用户看到不适当的信息。该方法只在由懂得有关保证数据私密性和完整性的规则并且有望从中受益的机构内部人员开发并验收应用程序的情形下才有效。

    在电子商务的世界里,这些假设都不再适用。数据库中的信息访问正向第三方应用程序以及其 SQL 内容随用户需求和上下文变化的应用程序开放。这意味着,为了确保将规则有效地应用于所有访问数据库的用户和应用程序而不管使用的是什么应用程序,必须将实施低层访问控制的责任推给数据库。这种改变还有利于访问控制策略的集中编码,因为这些策略都是由信息存储的数据库中的信息属主来实现并维护的。

    DB2 UDB 提供了种类繁多的机制,能用以根据用户不同的访问企图,实施相应的访问控制策略。这些机制包括表权限、列权限、视图和触发器。结合用户自定义的访问策略,可通过这些工具在 DB2 UDB 数据库中实现普遍的低层访问控制。

    虽然此论述适用于所有平台(包括 390 和 400),但下面的具体例子是在 DB2 UDB 的 UnixWindows 和 OS/2 版上执行的。

    定义访问控制策略

    来看如何实现低层安全的具体例子之前,我们必须回顾访问控制策略中需要定义什么。基本上,我们可以将该问题分为两部分:读访问控制和写访问控制。读访问控制特别与 SELECT 语句相关,而写访问控制则与 INSERT、UPDATE 和 DELETE 语句相关。为了成功地实现和维护一个访问策略,首先要对它进行清晰的定义。对于每行的读/写访问控制策略,需要回答以下问题:

      XMLns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dw="http://www.ibm.com/developerworks/">
    1. 如何定义一个用户?
      • 它是指一个指定的用户 ID 还是指一类用户?
      • 用什么来标识企图访问各行的用户?例如,可使用用户 ID、部门或城市来标识。
    2. 对于每个用户的访问请求,如何惟一地标识其一个或多个访问级别?
      • 每个用户是否可能有不止一种访问级别?
    3. 对每一行,如何惟一地标识其一个或多个访问级别?
      • 行中哪些属性将用于指明所需的访问级别?例如,可使用供应商、零件号或薪水来指明。
    4. 对一行中每个列,是否有惟一访问要求?如果有,如何惟一地标识它们?
      • 用户能否访问所有的列或某些列,或是否依据用户的访问级别来确定其可访问的列数?如果可访问的列数少于行中总列数,或是随请求者而变化,那么如何确定每个子集的访问级别?
    5. 读和写的行记录集合是否以任何方式相交?
      • 它们是否重叠?一个是否为另一个的子集?

    一旦清晰地定义了这些元素,行和列级上的安全的访问控制策略就可以实现。例如,如果某公司有一张表,包含了所有雇员的信息,那么,该 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
    #p#分页标题#e#

    列访问策略

    列内容 公共访问 雇员访问 人力资源访问 管理访问
    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列中的用户定义为公司的雇员。
    #p#分页标题#e#

    人力资源

    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 权限。

    要进一步阐述前面给定的雇员信息表上的访问策略示例,我们可以先定义所需的表和数据,如下列 SQL 语句所示。为了使示例保持清晰,我们简化了该场景  

    — 创建 department 表
    create table bigco.department   (department_id                 char(4) not null primary key,
      department_info    varchar(255));
    — 创建 employee 信息表
    create table bigco.employee    (employee_id          int not null primary key,
      employee_userid    char(30) not null unique,
      employee_info   varchar(255),
      employee_evaluation   char(4) default ‘ ‘,
      department_id   char(4) not null
          references bigco.department);
    — 插入部门信息
    insert into bigco.department values (‘d111’, ‘Marketing’), (‘d222’,’Inventory Control’),
      (‘d333’,’Accounting’), (‘d789’,’Human Resources’),
      (‘d666’,’Management’);
    — 插入雇员信息
    insert into bigco.employee values (1, ‘HUGO’,’some fascinating tidbits’,’A111’,’d666’),
      (2, ‘MARY’,’some fascinating tidbits’,’B212’,’d789’),
      (3, ‘FRUITFLY’,’some fascinating tidbits’,’FFFF’,’d111’),
      (4, ‘PBIRD’,’some fascinating tidbits’,’B114’,’d222’),
      (86,’MAX’,’some fascinating tidbits’,’A32A’,’d333’);
    #p#分页标题#e#

    一旦定义了这些基本表,通过使用视图和授予 SELECT 权限,我们就可以实现之前为雇员信息表定义的读访问策略了。本例中,我们可以使用两个视图定义:一个允许雇员查看他们自己的行,另一个则允许管理部门和人力资源(HR)部门的成员查看 employee 表中的全部行。

    — 创建这样的视图,以允许雇员访问 employee 表中自己的行和某些列
    create view bigco.employee_Access
      (Employee_ID, User_ID, Employee_Information, Department_ID) as
    (select employee_id, employee_userid, employee_info, department_id
    from employee
    where employee_userid = USER);
    — 允许所有雇员读访问 employee 视图
    grant select on bigco.employee_access to public;
    — 创建这样的视图,以允许 HR 部门和管理部门访问所有的行
    create view bigco.mgmt_access
      (Employee_ID, User_ID, Employee_Information, Department_ID, Employee_Evaluation) as
    (select employee_id, employee_userid, employee_info, department_id,
    — 如果是管理部门中的雇员,那么只允许
      — 管理部门中的用户看到 Evaluation 表
        case when (department_id = ‘d666’)
          then case (select department_id
              from bigco.employee as x
    where x.employee_userid = USER)
            when ‘d666’ then employee_evaluation
    else ‘N/A’
          end      
            else employee_evaluation
        end        
      from bigco.employee);
    — 允许管理部门和 HR 部门的所有成员读访问 management 视图
    grant select on bigco.mgmt_access to group d666, group d789;
    #p#分页标题#e#

    如下面的例子所示,基于使用不同的视图及其用户信息,我们将得到不同的结果。请注意 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 表所作的选择(无访问权限)
    select * from bigco.employee;
    SQL0551N “PBIRD” does not have the privilege to perform operation “SELECT”
    on object “BIGCO.EMPLOYEE”. SQLSTATE=42501.

    — 由管理部门的雇员(HUGO)对 employee 表所作的选择(无访问权限)
    select * from bigco.employee;
    SQL0551N “HUGO” does not have the privilege to perform operation “SELECT”
    on object “BIGCO.EMPLOYEE”. SQLSTATE=42501.

    — 由非 HR 部门的雇员(PBIRD)对 employee_access 视图所作的选择
    select employee_id, user_id, department_id from bigco.employee_access;
    EMPLOYEE_ID        USER_ID                                                               DEPARTMENT_ID
    ——————————- ——————————————— ————————————-
                                         4 PBIRD                                                                         d222
    1 record(s) selected.

    #p#分页标题#e#

    — 由管理部门的雇员(HUGO)对 employee_access 视图所作的选择
    select employee_id, user_id, department_id from bigco.employee_access;
    EMPLOYEE_ID        USER_ID                                                               DEPARTMENT_ID
    ——————————- ——————————————— ————————————-
                                         1 HUGO                                                                         d666
    1 record(s) selected.

    — 由非 HR 部门的雇员(PBIRD)对 mgmt_access 视图所作的选择(无访问权限)
    select employee_id, user_id, employee_evaluation from bigco.mgmt_access;
    SQL0551N “PBIRD” does not have the privilege to perform operation “SELECT”
    on object “BIGCO.MGMT_ACCESS”. SQLSTATE=42501.

    — 由 HR 部门的雇员(MARY)对 mgmt_access 视图所作的选择(隐藏了 management evaluations)
    select employee_id, user_id, employee_evaluation from bigco.mgmt_access;

    EMPLOYEE_ID        USER_ID                                                      EMPLOYEE EVALUATION
    ——————————- ——————————————— ————————————-
                                         1 HUGO                                                                        N/A
                                         2 MARY                                                                        B212
                                         3 FRUITFLY                                                                 FFFF
                                         4 PBIRD                                                                        B114
                                         86 MAX                                                                        A32A
    5 record(s) selected.

    #p#分页标题#e#

    — 由管理部门对 mgmt_access 视图所作的选择(显示所有 evaluations)
    select employee_id, user_id, employee_evaluation from bigco.mgmt_access;
    select employee_id, user_id, employee_evaluation from bigco.mgmt_access;

    EMPLOYEE_ID        USER_ID                                                        EMPLOYEE EVALUATION
    ——————————- ——————————————— ————————————-
                                         1 HUGO                                                                        A111
                                         2 MARY                                                                        B212
                                         3 FRUITFLY                                                                 FFFF
                                         4 PBIRD                                                                        B114
                                         86 MAX                                                                        A32A
    5 record(s) selected.

    #p#分页标题#e#

     


    评论 {{userinfo.comments}}

    {{money}}

    {{question.question}}

    A {{question.A}}
    B {{question.B}}
    C {{question.C}}
    D {{question.D}}
    提交

    驱动号 更多