管理权限


上文我们讲到了最简单的授权——继承固定角色,而没有说明如何为自订角色分配权限,现在我们来说说如何自定义分配权限的问题,包括 权限分类, 安全对象的常用权限, 授予权限, 撤销权限, 否认权限几个方面.

权限分类

大体上而言,权限可以分为两类: 预先定义的权限、预先未定义的权限,它们的区别如下:

  • 预先定义的权限: 系统自带的权限,指系统安装之后无需进行授予就有的权限,如固定角色拥有的权限.
  • 预先未定义的权限: 需要通过继承/授予才能得到的权限,授权者一般是管理员.

从对象的角度上看,权限还可以分为另外两类:

  • 针对特殊对象的权限,如INSERT权限.
  • 针对所有对象的权限,如ALTER权限.

下面列出了针对所有对象的一些权限:

权限 作用
CONTROL 对特定安全对象有控制权,包括对其所有子对象的控制权(一切权限)
ALTER 更改特定安全对象的权限
ALTER ANY 更改任意安全对象的权限
TAKE OWNERSHIP 所有权转移,获得对特定安全对象的所有权
INPERSONATE 模拟指定登录名/用户进行对应操作,授权是临时的
CREATE 创建服务器安全对象、数据库安全对象、架构内安全对象的权限
VIEW DEFINITION

下面列出了针对指定安全对象的一些权限:

权限 作用对象 作用
SELECT 同义词、表和列、表值函数、视图和列等 检索数据权限
UPDATE 同义词、表和列、视图和列等 更新数据权限
REFERENCES 标量函数、聚合函数、队列、表和列、表值函数、视图和列等 引用对象权限
INSERT 同义词、表和列、视图和列等 插入数据权限
DELETE 同义词、表和列、视图和列等 删除数据权限
EXECUTE 同义词、标量函数、聚合函数、过程等 执行操作权限

具体操作不再举例说明,会在后面逐渐接触相应操作.

对象的常用权限

从对象的角度看待权限,往往不同的安全对象对应不同的权限,在授权/撤销操作时,应注意不要搞混对象和权限的对应关系,下表列出了安全对象的常用权限:

安全对象 常用权限
数据库 BACKUP DATABASEBACKUP LOGCREATE DATABASECREATE DEFAULTCREATE FUNCTIONCREATE PROCEDURECREATE RULECREATE TABLECREATE VIEW
SELECTDELETEINSERTREFERENCES
表值函数 SELECTDELETEINSERTREFERENCES
视图 SELECTDELETEINSERTREFERENCES
存储过程 EXECUTESYNONYM
标量函数 EXECUTEREFERENCES

授予权限

使用GRANT关键字可授予安全对象权限,授权时经常使用ALL表示授予安全对象所能拥有的所有权限.

USE Temp 
GO

GRANT CONTROL TO Alex;	--将数据库所有权授予Alex;
GO

GRANT CONNECT TO guest;	--激活guest;
GRANT CREATE TABLE TO guest;	--建表权授予guest;
GO

GRANT CREATE TABLE TO Aveline	--建表权授予Aveline;
	WITH GRANT OPTION;	--且允许Aveline授予其它用户建表权;
GO

上面的代码注释很详细,唯一值得一提的就是WITH GRANT OPTION选项,该选项是指定被授权对象拥有将该权限转授的权限.请看以下的例子:

USE AdventureWorks2017;
GO

GRANT SELECT ON Sales.Customer TO Aaron;	--将表的SELECT权限授予Aaron;
GO

GRANT SELECT ON OBJECT::Sales.CurrencyRate TO Aaron	--将表的SELECT权限授予Aaron;
	WITH GRANT OPTION;
GO

GRANT SELECT ON Sales.Store(Name,SalesPersonID) TO Aaron;	--将表指定列的SELECT权限授予Aaron;
GO

分析:

  • 第一段授权,使用Sales作为架构名,对Sales架构下的Customer表的SELECT权限授予用户,若不指定架构,则默认使用当前用户默认的架构名,并不建议不指定架构.
  • 第二段授权,使用了OBJECT::作为表的限定符,OBJECT::表示对象,可以省略.
  • 第三段授权,对Sales.Store中的两列(Name,SalesPersonID)的SELECT权限授予用户,这说明,权限管理方面可以不以整个表为单位,而是以列为单位,即权限可以设置的很细,如下图:

从左侧栏可见,Sales.Store表有很多列,这样授权后,Aaron只拥有对Name和SalesPersonID两列的SELECT权限

还可以对其他对象授权,不仅仅针对用户.比如可以对登录名/自定义角色进行授权,就不一一举例了.


关于GRANT授权,需要注意几点:

  • 不同的安全对象拥有不同类型的权限,授权时需要对号入座.
  • 授予其它对象权限的对象,至少需要有GRANT OPTION权限,或者是隐含的最高权限(如sa).

撤销权限

使用REVOKE关键字可撤销安全对象权限,撤销时经常使用ALL表示撤销安全对象所拥有的所有权限.

注: REVOKEGRANT是一对相对关键字,REVOKE只能撤销GRANT授予的权限.

针对上面的例子,使用REVOKE撤销权限:

USE AdventureWorks2017;
GO

REVOKE SELECT ON Sales.Customer FROM Aaron;	--撤销Aaron对表的SELECT权限;
GO

REVOKE SELECT ON OBJECT::Sales.CurrencyRate FROM Aaron	--撤销Aaron对表的SELECT权限;
GO

REVOKE SELECT ON Sales.Store(Name,SalesPersonID) FROM Aaron;	--撤销Aaron对表指定列的SELECT权限;
GO

得到错误提示如下:

第7行,也就是对Sales.CurrencyRate的SELECT权限撤销失败,原因是在授权时使用了GRANT OPTION选项:

按照语法REVOKE只能撤销SELECT权限,而GRANT OPTION权限没有撤销,这就导致对象可以通过GRANT OPTION授予其他对象GRANT OPTION权限,再通过该对象反授权于自身,从而再次获得SELECT权限.

为了避免上面的情况发生,SQL提供了一种可将GRANT OPTION撤销的方法–通过关键字CASCADE(级联)撤销:

USE AdventureWorks2017;
GO

REVOKE SELECT ON OBJECT::Sales.CurrencyRate	--撤销Aaron对表的SELECT权限;
	FROM Aaron CASCADE;
GO

使用REVOKE的注意点:

  • REVOKE只能撤销GRANT授予的权限.
  • CASCADE用于撤销GRANT OPTION.
  • REVOKEGRANT作用的安全主体范围一致.

否认权限

由于REVOKE只能撤销GRANT授予的权限,当对象的权限不是用GRANT授予的,而是从角色继承过来时.就不可以用REVOKE撤销了,此时我们使用DENY来否认这些特定权限.


DENYGRANT用法大致相同,使用时需要注意几点:

  • DENY某项权限,则对象无法通过继承某个角色再次被授予该权限,对象进入了否认状态.
  • REVOKE可以撤销DENY的权限,使对象退出否认状态,恢复到自然状态.

下面是一个例子:

USE Temp;
GO

EXEC sp_addrolemember 'db_owner','Alex';
GO

DENY SELECT ON dbo.PriceTable TO Alex;	--否认Alex对表的SELECT权限;
GO

可以看到,即使是作为db_owner的成员,Alex也无法对表dbo.PriceTable进行SELECT操作:

Permission Denied

可以使用REVOKE撤销某个被DENY的权限,使对象回归自然状态:

USE Temp;
GO

REVOKE SELECT ON dbo.PriceTable FROM Alex;	--撤销Alex对表的SELECT权限,使其回到自然状态;
GO

自然状态用户Alex继承了db_owner角色,因此可以使用SELECT(虽然dbo.PriceTable然是一张空表):

空表

最后再说一点数据库的安全性设计思路:

  • 角色是权限的集合,权限应该先集中在角色中,再用相应对象继承.
  • 新建/使用模板定义数据库角色后,使用GRANT语句为角色赋予新权限,再用用户去继承权限.
  • REVOKE对于GRANT是撤销权限,对于DENY是撤销状态.
  • 特殊情况下可以绕过角色,直接对对象授予某种特权,但应该考虑安全性问题.

以上就是权限管理的全部内容,关于数据库管理的操作,请关注下文.

上一篇: 角色、用户、架构
下一篇: 管理数据库

猜你喜欢

转载自blog.csdn.net/AAMahone/article/details/88375125