本文属于「数据库系统」系列文章之一,这一系列着重于「数据库系统知识的学习与实践」。由于文章内容随时可能发生更新变动,欢迎关注和收藏数据库系统系列文章汇总目录一文以作备忘。需要特别说明的是,为了透彻理解和全面掌握数据库系统,本系列文章中参考了诸多博客、教程、文档、书籍等资料,限于时间精力有限,这里无法一一列出。部分重要资料的不完全参考目录如下所示,在后续学习整理中还会逐渐补充:
- 数据库系统概念 第六版
Database System Concepts, Sixth Edition ,作者是 Abraham Silberschatz, Henry F. Korth, S. Sudarshan ,机械工业出版社 - 数据库系统概论 第五版,王珊 萨师煊编著,高等教育出版社
4.2.2 存取控制
数据库安全最重要的一点就是,确保只授权给有资格的用户访问数据库的权限,同时令所有未被授权的人员无法接近数据,这主要通过数据库系统的存取控制机制实现。
存取控制机制主要包括定义用户权限和合法权限检查两部分。 (1)定义用户权限,并将用户权限登记到数据字典中:用户对某一数据对象的操作权力称为权限。某个用户应该具有何种权限是个管理问题和政策问题,而非技术问题。数据库管理系统的功能是,保证这些决定的执行。为此,数据库管理系统必须提供适当的语言来定义用户权限,这些定义经过编译后,存储在数据字典中,被称做安全规则或授权规则。 (2)合法权限检查:每当用户发出存取数据库的操作请求后(请求一般应包括操作类型、操作对象、操作用户等信息),数据库管理系统查找数据字典,根据安全规则进行合法权限检查,若用户的操作请求超出了定义的权限,系统将拒绝执行此操作。
定义用户权限和合法权限检查机制,一起组成了数据库管理系统的存取控制子系统。C2级的数据库管理系统支持自主存取控制 Discretionary Access Control, DAC ,B1级的数据库管理系统支持强制存取控制 Mandatory Access Control, MAC 。这两类方法的简单定义是:
- 在自主存取控制方法中,用户对于不同的数据库对象有不同的存取权限,不同的用户对于同一对象也有不同的权限,而且用户还可将其拥有的存取权限转授给其他用户。因此,自主存取控制非常灵活。
- 在强制存取控制方法中,每个数据库对象被标以一定的密级,每个用户也被授予某一级别的许可证,对于任意一个对象,只有具有合法许可证的用户才可以存取。强制存取控制因此相对比较严格。
下面介绍这两种存取控制方法。
1. 自主存取控制方法
大型数据库管理系统都支持自主存取控制,SQL标准也对自主存取控制提供支持,这主要通过SQL的 grant 语句和 revoke 语句来实现。
用户权限是由两个要素组成的:数据库对象和操作类型。定义一个用户的存取权限,就是要定义这个用户可在「哪些数据库对象」上进行「哪些类型的操作」。在数据库系统中,定义存取权限称为授权 authorization 。
在非关系系统中,用户只能对数据进行操作,存取控制的数据库对象也仅限于数据本身。在关系数据库系统中,存取控制的对象不仅有数据本身(基本表中的数据、属性列上的数据),还有数据库模式(包括数据库、基本表、视图和索引的创建等)。下表给出了关系数据库系统中的主要存取权限。 表4.3中,列权限包括 select, references, insert, update ,其含义与表权限类似。需要说明的是,对列的 update 权限,指对于表中存在的某一列的值可以进行修改。当然,有了这个权限之后,在修改的过程中还要遵守表在创建时定义的主键及其他约束。列上的 insert 权限,指用户可以插入一个元组,对于插入的元组,授权用户可以插入指定的值,其他列或者为空、或者为默认值。在给用户授予列 insert 权限时,一定要包含主键的 insert 权限,否则用户的插入动作会因为主键为空而被拒绝。
2. 授权与收回
SQL中使用 grant 和 revoke 语句,向用户授予或收回对数据的操作权限。grant 语句向用户授予权限,revoke 语句收回已经授予用户的权限。
(1) GRANT 的用法
grant 语句的一般格式为:
grant <权限>[, <权限>] ...
on <对象类型> <对象名>[, <对象类型> <对象名>] ...
to <用户>[, <用户>] ...
[with grant option];
其语义为:将对「指定操作对象」的「指定操作权限」授予「指定的用户」。发出该 grant 语句的,可以是数据库管理员,也可以是该数据库对象的创建者(即属主 owner ),还可以是已经拥有该权限的用户。接受权限的用户,可以是一个或多个具体用户,也可以是 public 即全体用户。
如果指定了 with grant option 子句,则获得某种权限的用户还可将这种权限再授予其他的用户。如果没有指定 with grant option 子句,则获得某种权限的用户只能使用该权限、不能传播该权限。SQL标准允许具有 with grant option 的用户,把相应权限或其子集传递授予其他用户,但不允许循环授权,即被授权者不能把权限再授回给授权者或其他祖先,如图4.4所示:
【例4.1】把查询 Student 表的权限授给用户 U1 。 答:
grant select
on table Student
to U1;
【例4.2】把对 Student 表和 Course 表的全部操作权限,授予用户 U2 和 U3 。 答:
grant all privileges
on table Student, Course
to U2, U3;
【例4.3】把对表 SC 的查询权限授予所有用户。 答:
grant select
on table SC
to public;
【例4.4】把查询 Student 表和修改学生学号的权限,授给用户 U4 。 答:这里实际上要授予 U4 用户的是,对基本表 Student 的 select 权限和对属性列 Sno 的 update 权限。对属性列授权时,必须明确指出相应的属性列名。
grant update(Sno), select
on table Student
to U4;
【例4.5】把对表 SC 的 insert 权限授予 U5 用户,并允许将此权限再授予其他用户。 答:执行以下的SQL语句后,U5 不仅拥有了对表 SC 的 insert 权限,还可以传播此权限。即由 U5 用户发出 grant 命令给其他用户,例如 U5 可将此权限授予 U6 (【例4.6】)。
grant insert
on table SC
to U5
with grant option;
【例4.6】U5 用户将对表 SC 的 insert 权限授予 U6 用户,并允许将此权限再授予其他用户。 答:U6 还可以将此权限授予 U7 (【例4.7】)。
grant insert
on table SC
to U6
with grant option;
【例4.7】U6 用户将对表 SC 的 insert 权限授予 U7 用户。 答:U7 不能再传播此权限,因为 U6 未给 U7 传播的权限。
grant insert
on table SC
to U6
with grant option;
由上面的例子可以看到,grant 语句可以一次向一个用户授权,如【例4.1】,这是最简单的一类授权操作;也可以一次向多个用户授权,如【例4.2】、【例4.3】;还可以一次传播多个同类对象的权限,如【例4.2】;甚至一次可以完成对基本表和属性列这些不同对象的授权,如【例4.4】。表4.4是执行了【例4.1】~【例4.7】的语句后,学生-课程数据库中的用户权限定义表:
(2) REVOKE 的用法
授予用户的权限,可由数据库管理员或其他授权者用 revoke 语句收回,revoke 语句的一般格式为:
revoke <权限>[, <权限>] ...
on <对象类型> <对象名>[, <对象类型> <对象名>] ...
from <用户>[, <用户>] ...
[cascade | restrict ];
【例4.8】把用户 U4 修改学生学号的权限收回。 答:
revoke update(Sno)
on table Student
from U4;
【例4.9】收回所有用户对表 SC 的查询权限。 答:
revoke select
on table SC
from public;
【例4.10】把用户 U5 对 SC 表的 insert 权限收回。 答:将用户 U5 的 insert 权限收回的同时,级联 cascade 收回了 U6, U7 的 insert 权限,否则系统将拒绝执行该命令。因为在【例4.6】中,U5 将对 SC 表的 insert 权限授予了 U6 ,而 U6 又将其授予了 U7 (【例4.7】)。
revoke insert
on table SC
from U5 cascade;
注意,这里默认值为 cascade ,将自动执行级联操作,有的数据库管理系统默认值为 restrict 。如果 U6 或 U7 还从其他用户处获得对 SC 表的 insert 权限,则他们仍具有此权限,系统只收回直接或间接从 U5 处获得的权限。
表4.5是执行了【例4.8】~【例4.10】的语句后,学生-课程数据库的用户权限定义表: SQL提供了非常灵活的授权机制。数据库管理员拥有对数据库中所有对象的所有权限,并可根据实际情况,将不同的权限授予不同的用户。用户对自己建立的基本表和视图拥有全部的操作权限,并可用 grant 语句,把其中某些权限授予其他用户。被授权的用户如果有「继续授权」的许可,还可以把获得的权限再授予其他用户。所有授予出去的权限,在必要时又都可以用 revoke 语句收回。
可见,用户可以「自主」地决定将数据的存取权限授予何人、决定是否也将「授权」的权限授予别人。因此,称这样的存取控制是自主存取控制。
(3) 创建数据库模式的权限
grant, revoke 语句向用户授予或收回对数据的操作权限。对创建数据库模式一类的数据库对象的授权,则由数据库管理员在创建用户时实现。
create user 语句的一般格式如下:
create user <用户名> [with] [DBA | RESOURCE | CONNECT];
对 create user 语句说明如下:
- 只有系统的超级用户,才有权创建一个新的数据库用户;
- 新创建的数据库用户有三种权限:
CONNECT, RESOURCE, DBA ; create user 命令中,如果没有指定创建的新用户的权限,默认该用户拥有 CONNECT 权限。拥有 CONNECT 权限的用户,不能创建新用户、不能创建模式、也不能创建基本表,只能登录数据库。由数据库管理员或其他用户授予他应有的权限,根据获得的授权情况,他可以对数据库对象进行权限范围内的操作;- 拥有
RESOURCE 权限的用户,能创建基本表和视图,成为所创建对象的属主,但不能创建模式,不能创建新用户。数据库对象的属主可以使用 grant 语句,把该对象上的存取权限授予其他用户。 - 拥有
DBA 权限的用户,是系统中的超级用户,可以创建新用户、创建模式、创建基本表和视图。DBA 拥有对所有数据库对象的存取权限,还可以把这些权限授予一般用户。
以上说明可用表4.6来总结:
注意:create user 语句不是SQL标准,因此不同关系DBMS的语法和内容相差甚远。这里介绍该语句的目的,是说明对于数据库模式这一类数据库对象,也有安全控制的需要,也是要授权的。
3. 数据库角色
数据库角色,是被命名的一组与数据库操作相关的权限,角色是权限的集合。因此,可为「一组具有相同权限的用户」创建一个角色,使用角色来管理数据库权限,以简化授权的过程。
在SQL中,首先使用 create role 语句创建角色,然后用 grant 语句给角色授权,用 revoke 语句收回授予角色的权限。
(1) 角色的创建
创建角色的SQL语句格式是:
create role <角色名>;
刚刚创建的角色是空的,没有任何内容,可用 grant 为角色授权。
(2) 给角色授权
数据库管理员和用户可以利用 grant 语句,将权限授予某一个或几个角色。
grant <权限>[, <权限>] ...
on <对象类型> 对象名
to <角色>[, <角色>] ...;
(3) 将一个角色授予其他的角色或用户
如下语句将角色授予某个用户,或者授予另一个角色。这样,一个角色(例如角色
3
3
3 )所拥有的权限,就是授予它的所有角色(例如角色
1
1
1 和角色
2
2
2 )所包含的权限的总和。授予者或者是角色的创建者,或者拥有在这个角色上的 admin option 。
grant <角色1>[, <角色2>] ...
to <角色3>[, <用户1>] ...
[with admin option];
如果指定了 with admin option 子句,则获得某种权限的角色或用户,还可以把这种权限再授予其他的角色。 一个角色包含的权限,包括直接授予这个角色的全部权限,加上其他角色授予这个角色的全部权限。
(4) 角色权限的收回
用户可以收回角色的权限,从而修改角色拥有的权限。revoke 动作的执行者,或者是角色的创建者,或者拥有在这个(些)角色上的 admin option 。
revoke <权限>[, <权限>] ...
on <对象类型> <对象名>
from <角色>[, <角色>] ...;
【例4.11】通过角色来实现将一组权限授予一个用户。步骤如下: ① 首先创建一个角色 R1 :
create role R1;
② 然后使用 grant 语句,使角色 R1 拥有 Student 表的 select, update, insert 权限:
grant select, update, insert
on table Student
to R1;
③ 将这个角色授予王平、张明、赵玲,使他们具有角色 R1 所包含的全部权限。
grant R1
to 王平, 张明, 赵玲;
④ 当然,也可以一次性地通过 R1 来收回王平的这三个权限。
revoke R1
from 王平;
【例4.12】角色的权限修改。让角色 R1 在原来的基础上,增加 Student 表的 delete 权限。 答:下面
grant delete
on table Student
to R1;
【例4.13】让角色 R1 减少 select 权限。 答:
revoke select
on table Student
from R1;
可以看出,数据库角色是一组权限的集合,使用角色来管理数据库权限,可以简化授权过程,使自主授权的执行更加灵活、方便。
4. 强制存取控制方法
自主存取控制 MAC 能够通过授权机制,有效地控制对敏感数据的存取。但是由于用户对数据的存取权限是「自主」的,用户可以自由地决定将数据的存取权限授予何人,以及决定是否将「授权」的权限授予别人。在这种授权机制下,仍可能存在数据的无意泄露。比如,甲将自己权限范围内的某些数据存取权限授权给乙,甲的意图是仅允许乙本人操纵这些数据。但是甲的这种安全性要求并不能得到保证,因为乙一旦获得了对数据的权限,就可以将数据备份,获得自身权限内的副本,并在不征得甲同意的前提下传播副本。
造成这一问题的根本原因就在于,这种机制仅仅通过「对数据的存取权限」来进行安全控制,而数据本身并无「安全性标记」。要解决这一问题,就需要对系统控制下的所有主客体实施强制存取控制策略。
所谓强制存取控制,是指系统为了保证更高程度的安全性,按照 TDI/TCSEC 标准中安全策略的要求,所采取的强制存取检查手段。它不是用户能直接感知或进行控制的。强制存取控制适用于那些对数据有严格而固定密级分类的部门,例如军事部门或政府部门。
在强制存取控制中,数据库管理系统所管理的全部实体分为主体和客体两大类:
- 主体是系统中的活动实体,既包括数据库管理系统所管理的实际用户,也包括代表用户的各进程。
- 客体是系统中的被动实体,是受主体操纵的,包括文件、基本表、索引、视图等。
对于主体和客体,数据库管理系统为它们每个实例(值)指派一个敏感度标记 label ,这一标记分为若干级别,例如绝密 Top Secret, TS 、机密 Secret, S 、可信 Confidential, C 、公开 Public, P 等。密级的次序是 TS >= S >= C >= P 。
主体的敏感度标记称为许可证级别 clearance level ,客体的敏感度标记称为密级 classification level 。强制存取控制机制,就是通过对比主体的许可证级别和客体的密级,最终确定主体是否能够存取客体。
当某一用户(或某一主体)以标记 label 注册入系统时,系统要求他对任何客体的存取必须遵循如下规则: (1)仅当主体的许可证级别大于或等于客体的密级时,该主体才能读取相应的客体。 (2)仅当主体的许可证级别小于或等于客体的密级时,该主体才能写相应的客体。
规则1的意义是明显的,而规则2需要解释。按照规则2,用户可以为写入的数据对象赋予高于自己的许可证级别的密级。这样一旦数据被写入,该用户自己也不能再读该数据对象了。如果违反了规则2,就有可能把数据的密级从高流行低,造成数据的泄露。例如,某个 TS 许可证级别的主体,把一个密级为 TS 的数据恶意降低为 P ,然后把它写回。这样,大家都可以读到原来是 TS 密级的数据,造成 TS 密级数据的泄露。
强制存取控制是对数据本身进行密级标记,无论数据如何复制,标记与数据是一个不可分割的整体,只有符合密级标记要求的用户才可以操纵数据,从而提供了更高级别的安全性。前面已经提到,较高安全性级别提供的安全保护要包含较低级别的所有保护,因此在实现强制存取控制时,要首先实现自主存取控制 DAC ,即自主存取控制与强制存取控制共同构成数据库管理系统的安全机制,如下图所示。系统首先进行自主存取控制检查,对通过自主存取控制检查的、允许存取的数据库对象,再由系统自动进行强制存取控制检查,只有通过强制存取控制检查的数据库对象方可存取。
|