本篇文章记录了第十一次作业
使用的数据库是SQL Server,使用的数据库管理软件是SQL Server Management Studio.
大部分情况下,数据库中的数据是要通过互联网进行共享的。不共享的数据库可能像《三体》里面记录人类文明的墓地,那种为了保存而使用的数据库。那么既然要共享必然会有许多用户能够访问这一数据库,为了保护数据库内的数据不被不怀好意的用户恶意利用,数据库的安全性必然是数据库好坏的一个十分重要的方面。
由于安全对数据库来说十分重要,数据库为此提供了层层保护措施。
一般来说,一名用户若是要访问数据库,DBMS会首先对这名用户进行身份鉴别。通过之后在SQL处理层会进行存取控制,也就是对用户使用数据库的权限的控制,也是这篇文章主要记录的内容。同时系统会对这些操作进行记录,作为审计的依据。在数据层面,系统会对数据以及传输过程进行加密,保证数据不会被泄露。还有其他的保护措施在此就不一一介绍了。
数据库的存储控制的主要功能就是让有资格的用户来访问数据库,也就是一种资格审查。这个机制主要有两部分,一部分是定义记录用户权限,另一部分是合法权限检查。它同时负责“发证”和检查“证件”。
这种机制的实现有两种办法:一种是自主存取控制(Discretionary Access Control,DAC),另一种是强制存储控制(Mandatory Access Contrl,MAC).第一种方式比较灵活,而第二种方式比较严格,当然安全性也较高。
自主存取控制方法它灵活在哪呢?它主要是靠对用户的灵活授权来实现的。比如它可以对某一用户授予查询权限而不授予其修改的权限,亦或者是授予其全部权限。根据对象的不同,自主存取可以授予其不同的权限。利用“角色”可以实现按照用户的类型来分类管理的功能,十分方便。
我们一般使用SQL中的GRANT和REVOKE语句来实现权限的授予于收回。
GRANT语句用于向用户授予权限。其一般格式如下:
GRANT <权限>[,<权限>]...
ON <对象类型> <对象名>[,<对象类型> <对象名>]…
TO <用户>[,<用户>].../*可以授予PUBLIC,即全体用户*/
[WITH GRANT OPTION];
WITH GRANT OPTION这个语句的意思是授予用户再授权的权力。比如说我给这名用户授予了“查询”权限,那么如果我加上了这一句话,这名用户就可以把“查询”这一权限授予其他用户。如果没有WITH GRAND OPTION则是不能把权限再授予其他用户的。不过这种授权不允许授予其授权者以及授权者的先祖。
GRANT SELECT
ON TABLE Student
TO U1;
说来挺尴尬哈,我第二行在测试的时候少打了个TABLE。然后SQL Server那边是通过的,刚刚检查才发现这个问题。当我把TABLE加上去后直接报错…那么解决办法就是不加TABLE了SQL Server这边应该能自动识别(大概吧)。
下图是DBMS中U1的属性,可以看到在选择(SELECT)这一栏打上了一个勾。第一个框表明有这种权限,第二框是可以再授予权限,也就是加上WITH GRANT OPTION,第三个框是拒绝。这表明我们成功给U1授予了SELECT权限。
&emsp;这里要新建用户U2,U3。于是我按照之前创建U1的步骤那样做,但是报错。
这里是由于我选择了和U1同样的登录名。那行吧,我再创建几个呗。
CREATE LOGIN U3
WITH PASSWORD='123';
CREATE USER U3 FROM LOGIN U3;
这是建立了一个叫U3的用户名,并利用它建立了一个新用户U3。目前看来好像能用,有没有啥隐患我还不知道,先将就着用吧…
回归正题,这个例子按标准SQL应该这样写:
GRANT ALL PRIVILEGES
ON TABLE Student,Course
TO U2,U3;
去掉TABLE之后显示:“,”附近有语法错误。行吧,你逗号出错是什么鬼?可能是不支持一块儿写吧。试试分开写:
GRANT ALL PRIVILEGES
ON Student
TO U2,U3;
GRANT ALL PRIVILEGES
ON Course
TO U2,U3;
成了:
这里的提示表示微软不推荐再使用ALL来授权,这里只有便于兼容。那么用户是否被授予了全部权限呢?我打开属性一看,授予了用户更新、删除、选择、插入和引用的权限,还有一些权限并有授予,比如更改权限。所以这应该称不上是ALL,顶多算个“BASIC”吧(笑。
GRANT SELECT
ON TABLE SC /*T-SQL请去掉TABLE*/
TO PUBLIC;
这题告诉我们了全体用户是PUBLIC,比较简单,也很给我面子没有报错,hh.
GRANT UPDATE(Sno), SELECT /*对属性列授权时必须明确相应的属性列名*/
ON TABLE Student /*去掉TABLE*/
TO U4;
很给力,直接成功_(:з」∠)_
这明显就是说的我们之前讲的WITH GRANT OPTION嘛,直接加上就完事儿了。
GRANT INSERT
ON TABLE SC
TO U5
WITH GRANT OPTION;
GRANT INSERT /*U5将权限授予U6*/
ON TABLE SC
TO U6
WITH GRANT OPTION;
GRANT INSERT /*U6将权限授予U7,U7不可再授予*/
ON TABLE SC
TO U7;
这两题就是展示WITH GRANT OPTION的实例,不过实际上如果你直接再SQL Server中输入的话,还是dbo(默认的用户)授予的权限。这里需要使用到AS语句。
也就是这样:
GRANT INSERT /*U5将权限授予U6*/
ON SC
TO U6
WITH GRANT OPTION AS U5;
GRANT INSERT /*U6将权限授予U7,U7不可再授予*/
ON SC
TO U7 AS U6;
可以看到这里U7的权限授予者变为了U6,否则就是默认的dbo。
授予了权限当然也可以收回,我们用REVOKE语句来收回权限。语句的一般格式如下:
REVOKE <权限>[,<权限>]...
ON <对象类型> <对象名>[,<对象类型><对象名>]…
FROM <用户>[,<用户>]...[CASCADE | RESTRICT];
大体上跟GRANT语句类似,不过把TO改成了FROM,另外后面可能会加上CASCADE or RESTRICT,这俩怎么用我们碰到具体题目再说。
REVOKE UPDATE(Sno) /*注意这里要加上具体属性名*/
ON TABLE Student
FROM U4;
REVOKE SELECT
ON TABLE SC
FROM PUBLIC;
同授予全部用户SC表查询权限操作类似。
这里要注意的是U5对SC表的INSERT权限不仅仅只有U5,还有他授予的U6以及U6授予的U7,这时候就要使用CASCADE了。
REVOKE INSERT
ON TABLE SC
FROM U5 CASCADE;
经过测试,所有相关的权限都收回了。
可见,用户可以“自主”地决定将数据的存取权限授予何人、决定是否也将“授权”的权限授予别人因此称这样的存取控制是自主存取控制。
数据库角色是被命名的一组与数据库操作相关的权限,角色是权限的集合。因此可以为一组具有相同权限的用户创建一个角色,使用角色来管理数据库权限可以简化授权的过程。整体上我觉得这一块就像面向对象程序设计里面的class,可以批量授予或者收回权限,比较方便。
创建角色的SQL语句格式是:
CREATE ROLE <角色名>
但是这样的角色是空的,没有任何内容,所以我们需要用GRANT来为角色授权。
语句格式如下:
GRANT <权限>[,<权限>]…
ON <对象类型>对象名
TO <角色>[,<角色>]…
只是把用户改成了角色,其他基本一样。
格式如下:
GRANT <角色1>[,<角色2>]…
TO <角色3>[,<用户1>]…
[WITH ADMIN OPTION]
角色可以给角色授权,就像之前的视图可以以视图为基本建立视图。WITH ADMIN OPTION用途与之前的类似,也是授予这个用户或者角色再次授予的权限。一个角色包含的权限包括直接授予这个角色的全部权限加上其他角色授予这个角色的全部权限。
格式如下:
REVOKE <权限>[,<权限>]…
ON <对象类型> <对象名>
FROM <角色>[,<角色>]…
下面来看看例子
CREATE ROLE R1; /*首先创建一个角色R1*/
GRANT SELECT,UPDATE,INSERT
ON TABLE Student
TO R1;
GRANT R1
TO U1,U2,U3;
REVOKE R1
FROM U3;
前两段可以在SQL Server上正常运行,但是后两段不行。上网查文件T-SQL里面得这样写:
也就是这样:
ALTER ROLE R1 ADD MEMBER U1; /*直接写U1,U2,U3会报错,不知道是不是只能这样写*/
ALTER ROLE R1 ADD MEMBER U2;
ALTER ROLE R1 ADD MEMBER U3;
ALTER ROLE R1 DROP MEMBER U3; /*这样写成功运行了*/
我的U1是使用##MS_PolicyEventProcessingLogin##作为登录名的,角色里面也有U1,但是属性里面看不到它的授权信息,不知道为什么-_-
GRANT DELETE /*为角色增加了删除的权限*/
ON TABLE Student
TO R1;
REVOKE SELECT /*使R1减少了SELECT权限*/
ON TABLE Student
FROM R1;
自主存取控制可能存在数据的“无意泄露”,这是因为这种机制仅仅通过对数据的存取权限来进行安全控制,而数据本身并无安全性标记。这个时候就需要我们对系统控制下的所有主客体实施强制存取控制策略
强制存取控制的检查手段较为严格,但不灵活,适用于政府或者军队这类对数据有严格固定密级分类的部门。
&强制存取控制把DBMS中的全部实体分为主体和客体。主体是系统中的活动实体,比如用户;客体是系统中的被动实体,比如表等。DBMS为它们分配了一个敏感度标记也就是保密级别。比如绝密(Top Secret)>=机密(Secret)>=可信(Confidencial)>=公开(Public) 这一密级次序,通过比较两者的密级(主体叫做许可证级别)来判断主体对客体的操作权限。
规则如下:
也就是说许可证级别大只能读取,而许可证级别小只能写入而不能读取,只有级别符合的用户才能既读又写。这样就有效避免了底层人员窃取机密,也避免了高层瞎改东西,比如把绝密的东西改成公开导致泄密。
之前说到视图的时候也提到了视图可以用来保密这一点,就是建立一个视图只包含想要提供给用户的属性值来防止直接使用基本表令其他的属性值泄露。这里我们学了GRANT后就可以将视图授权给用户了。
CREATE VIEW CS_Student /*建立视图*/
AS
SELECT *
FROM Student
WHERE Sdept='CS';
GRANT SELECT
ON CS_Student
TO U4;
GRANT ALL PRIVILEGES
ON CS_Student
TO U5;
这里就是建立视图后用GRANT语句给用户授予权限。
课本上提到的“存取谓词”我google了一下没有任何信息…机翻后用英文搜索了一下,好像人家讲的Access predicate 和这不是一个玩意儿。根据书上的说法可能就是某一种谓词能够直接完成授权用户视图权限这一操作吧。
数据库安全里的审计是指对用户操作进行记录,然后通过数据分析来判断用户是否存在违规操作。具体怎么审计我们在此就不说了。
我们用AUDIT来设置审计,NOAUDIT取消审计。
AUDIT ALTER,UPDATE /*对SC表的ALTER和UPDATE操作进行审计*/
ON SC;
NOAUDIT ALTER,UPDATE /*取消对这两个操作的审计*/
ON SC;
这在SQL Server上又不管用。查了一下,你可以右键安全性中的数据库审核规范来创建审计,或者是使用T-SQL。
网址:https://docs.microsoft.com/zh-cn/sql/relational-databases/security/auditing/create-a-server-audit-and-database-audit-specification?view=sql-server-ver15
这有点复杂,我还没搞懂o(╥﹏╥)o
参考文献:
[1]萨师煊,王珊,数据库系统概论.5版.北京:高等教育出版社,2014.
[2]David老师的PPT.