Security 10:权限管理

在进行权限管理时,应遵照“最低权限”原则,即每一个人只授予必需的最小权限。相对于授予的权限,数据库中还有一个特殊的权限,那就是全部权(Ownship)。sql

SQL Server 用于管理权限的TSQL命令有:GRANT用于授予权限,REVOKE 用于移除已经被GRANT/DENY的权限,而DENY用于防止安全主体经过GRANT得到权限。DENY一旦执行,Principal在Securable上的权限就被禁用了。可是,SQL Server的权限空间不是扁平的,是立体的,在不一样的安全上下文(Security context)中,不一样的权限空间(Permission Space)中,这三个命令的优先级是不一样的。这就意味着,即便执行GRANT授予权限,用户不必定有权限,这是由于在特定的权限空间里,Deny命令禁用了用户的权限,同时Grant命令的优先级低于Deny。数据库

一,管理权限的规则

在管理权限时,要注意权限的上下文、权限的立体空间和权限的优先级安全

1,安全上下文和权限空间函数

安全上下文(Security Context),是跟user 或 login 相关的环境,用户能够经过EXECUTE AS 来切换安全上下文。安全上下文主要包括:Login、User、Role membership、Windows Group membershipurl

权限空间,是指安全对象(Securable)和包含安全对象的全部安全对象类(Securable class),好比,表包含在schema 中,schema是表的安全对象类;而database包含schema,database是schema的安全对象类。访问表的权限,受到表、schema和database的权限的影响,这三个对象构成一个权限空间,访问受到权限空间的约束。spa

2,权限的优先级.net

当这三个命令做用于同一个安全对象(Securable)时,状况会变得复杂,不只须要考虑权限空间,还须要考虑权限的优先级。3d

  • 在同一个安全主体范围内对同一个安全对象设置权限,GRANT子句会移除DENY和REVOKE子句设置的权限,这三个命令的优先级相同,后执行的语句会移除先执行语句的效果。
  • 可是,当相同的权限做用于同一安全主体的不一样范围时,若是DENY 做用于更高的范围内,那么DENY优先,可是在更高的范围内,REVOKE不优先。
  • 这里有一个例外,列级别的GRANT语句,会覆盖Object级别的DENY语句,可是后续Object级别的DENY语句会覆盖列级别的GRANT语句。

权限是累积的,一个User能够经过多种途径(好比Grant、Role和Group memberhsip)来得到受权,Revoke只能回收某一个途径上的权限,可是Deny会禁止用户得到受权。server

举个例子,一个User经过Grant得到表1的SELECT权限,经过Role得到表1的SELECT权限:对象

  • 状况1:当使用REVOKE命令回收GRANT授予的SELECT 权限时,该User仍然能够经过Role的权限来查询表1。
  • 状况2:当使用DENY命令拒绝表1的权限时,该User没有权限查询表1。

3,权限的层次结构

权限的层次结构是一种父子结构,拥有父级别对象的权限,默认拥有全部子级别对象的权限。举个例子,若是有数据库级别的SELECT权限,那么就有了数据库下全部Schema的SELECT权限;若是有Schema的SELECT权限,那么就有了Schema下全部对象的SELECT权限,这种权限的结构构成权限空间。

权限是一个覆盖式的权限,举个例子,Control表示全部的权限,当对一个对象授予Control权限,意味着授予全部其余的权限。

数据库级别的权限:

  • 在数据库级别授予操做数据库对象的权限,好比 EXECUTE、DELETE、INSERT、SELECT、UPDATE、REFERENCES、VIEW DEFINITION,实际上,授予的是操做数据库中全部对象的权限。
  • 数据库级别独有的权限:ALTER、BACKUP DATABASE、BACKUP LOG、CHECKPOINT、CONNECT、CREATE TABLE、CREATE VIEW、CREATE PROCEDURE等

二,权限管理的实现

权限管理涉及到Principal、Securable和Permission三个概念。Principal能够是单个User,也能够是多个User构成的Windows Group;Securable能够是单个数据库对象,也能够是包含多个数据库对象的schema;同时,User也能够经过role得到数据库对象的权限。

第一种方式,为每个User设置单个Securable的权限

 第二种方式,建立Windows Group,把User分组,为每个Windows Group设置单个Securable的权限,简少了受权用户的数量。

第三种方式,经过数据库 role来设置权限,经过Role来组织Securable,减小了受权对象的数量。

第四种方式,经过Schema来设置权限,在一个Schema下包含多个Securables,并经过Role来管理Scurable,经过Windows Group来管理User,这种方式虽然复杂,可是权限的管理很是精细和灵活。

三,全部权和全部权链

对象的全部者对一个对象拥有全部可能的权限,而且这些权限不能禁止。CONTROL权限能够执行与对象全部者几乎相同的操做,可是全部权和受权是不一样的。对象的全部者一般是其建立者,可是能够在建立时使用AUTHORIZATION子句指定其余全部者,也能够把Ownship转移给其余Principal。

如何在不授予基础表访问权限的状况下,仅对视图或任何其余类型的程序授予SELECT权限呢?答案是使用全部权链(Ownership-chaining)。一般状况下,当用户从视图中查询数据时,系统作两次权限检查,第一次是检查用户是否有权限查询视图,第二次是在视图引用基础表时检查用户是否有权限查询基础表,因为用户没有基础表的权限,所以第二次权限检查失败。

全部权链(Ownership-chaining)经过绕过第二次权限检查来避免这种状况,不然将在视图引用基础表时进行第二次权限检查。当连接的对象(underlying table)与调用对象(view)具备相同的全部者时,权限检查将被彻底绕开。

若是一个user在具备Ownership权限的Schema中建立视图,由于它视图的全部者,就是被视图引用的基表的全部者,这是一个链:我是Schema的全部者,那么Schema下的全部对象的Owner都是我,我有权限访问视图,但不能访问基础表。

 

全部权链只适用于SELECT, INSERT, DELETE, UPDATE 和MERGE,以及 SP和函数的EXECUTE 权限,出于安全考虑,不适用于使用动态SQL的程序中。要在SP、函数和触发器中执行动态SQL操做,须要使用使用WITH EXECUTE AS子句使用权限模拟。只要调用者对动态SQL中引用的数据库对象没有权限,就可使用此EXECUTE AS子句,但要格外当心。它经过将执行上下文切换到模拟用户来实现。全部代码,甚至是嵌套模块,都将在模拟用户的安全上下文中执行。当前正在执行的批处理在执行代码时会临时得到例程全部者的权限,而不是全部者的身份。这样,用户只能经过更改正在执行的代码来将特权用于任何其余目的。仅在过程执行完成后或在REVERT语句上,执行上下文才还原为原始调用方。

全部权链的问题在于,除了第一次权限检查以外,全部权连接会彻底绕过权限检查,甚至都优先于DENY ACCESS。

 

参考文档:

Getting Started with Database Engine Permissions

Schema-Based Access Control for SQL Server Databases

Permissions (Database Engine)

相关文章
相关标签/搜索