4.12 数据库安全
安全是一个很重要的话题,可以影响到几乎每个SQL Server用户(包括管理员和开发人员)的每一步动作,需要用一整本书来讨论它。然而,SQL Server安全框架的一些领域对理解怎样使用一个SQL Server数据库和数据库中的任一对象至关重要,并且SQL Server 2005的安全领域已经历巨变,所以我们也不能完全不讨论该话题。
SQL Server管理着一套分成各个级别的实体。这些实体中最为显著的就是服务器和服务器上的数据库。数据库层之下是对象。服务器层以下的每一实体都为单个用户或者用户组所有。SQL Server安全框架控制着对SQL Server实例中的实体的访问。就像任何资源管理器一样,SQL Server安全模型包含两部分:身份验证和授权。
身份验证(Authentication)是SQL Server校验和确定一个想要访问某个资源的用户身份的过程。授权(Authorization)是SQL Server决定是否允许某种身份的用户访问一种资源的过程。
本节我们将会讨论数据库访问的基本问题,然后描述存储有数据库访问信息的元数据。我们还会讨论SQL Server中的一个称为架构的新概念,并描述如何使用架构来访问对象。
SQL Server 2005使用一些新术语来描述SQL Server安全模型的各种特性,并且一些老术语也被以稍微不同的方式使用。特别是下面两个术语与在SQL Server 2000中相比有着更为广泛的含义:
安全实体(Securable) 在SQL Server 2000中作为一个对象,一个安全实体是一个可以被授予权限的实体。安全实体包括数据库、架构和对象。
主体(Principal) 在SQL Server 2000中作为一个用户,一个主体就是一个能够访问安全实体对象的实体。一个一级主体(Primary Principal)代表一个用户(例如一个SQL Server或Windows登录账户),一个二级主体(Secondary Principal)代表多个用户(例如一个角色或一个Windows用户组)。
数据库访问
SQL Serve中的身份验证分两级进行。首先,任何想要访问任一SQL Server资源的用户必须在服务器级别进行认证。SQL Server 2005安全提供了两种基本的验证用户登录账户的方法:Windows身份验证和SQL Server身份验证。在Windows身份验证中,SQL Server的登录账户安全与Windows的安全直接集成在一起,允许操作系统来对SQL Server的用户进行验证。 在SQL Server身份验证中,管理员在SQL Server内部创建SQL Server登录账户,任何连接SQL Server的用户必须提供有效的SQL Server登录账户名和密码。
Windows身份验证使用了信任连接(trusted connections),这依赖于Windows的模拟特性。通过模拟,SQL Server能够使用Windows用户账户的安全上下文来初始化连接并测试这个安全标识符(SID)是否具有足够的权限级别。当连接到SQL Server时,Windows模拟和信任连接为所有的网络库所支持。
在Windows 2000和Windows 2003中,SQL Server能够利用Kerberos来支持在客户端和服务器之间进行的多种验证,还可以通过将客户端的安全证明在计算机之间传递,使得被模拟客户端的安全证明的任务能够在远程计算机上继续进行。在Windows 2000和Windows 2003中,SQL Server使用Kerberos和委托(delegation)来支持Windows身份验证和SQL Server身份验证。
SQL Server使用的身份验证方法取决于它的安全模式。SQL Server能够运行在两种安全模式下:Windows 身份验证模式(这时只使用Windows身份验证)和混合模式(这时客户端可以选择使用Windows身份验证或SQL Server身份验证)。当我们连接到一个配置为使用Windows身份验证模式的SQL Server实例时,不能使用SQL Server登录名并且我们的Windows用户名决定了可以对SQL Server进行的访问的级别。
Windows身份验证的一个优势一直都是它允许SQL Server利用操作系统的安全特性,例如密码加密、密码过期,以及对密码的最少和最多长度的限制。对SQL Server 2005来讲,当运行在Windows 2003之上时,SQL Server身份验证也能够利用Windows的密码策略。要了解更多细节可以查看联机丛书的ALTER LOGIN命令。SQL Server 2005中的另一项改变是如果我们在安装时选择了Windows身份验证,那么SQL Server默认的sa登录账户会被禁止。如果我们在安装之后切换到混合模式,那么就可以使用ALTER LOGIN命令来启用sa登录账户。可以通过在SQL Server Management Studio中右击服务器名称,选择属性,然后选择安全页面来更改身份验证模式。在服务器身份验证之下,选择新的服务器身份验证模式,如图4-5所示。
|
图4-5 在服务器属性对话框中为SQL Server实例选择身份验证模式
在混合模式下,基于Windows的客户端能够通过Windows身份验证进行连接,来自非Windows客户端或来自Internet客户端的连接可以使用SQL Server身份验证。另外,当一个用户连接到一个安装时指定为混合身份验证的SQL Server实例时,可以通过显式地指定SQL Server登录账户名来进行连接。这允许使用不同于Windows中的用户名的登录账户来建立连接。
所有的登录账户名,或者是来自Windows,或者是来自SQL Server身份验证,都能从目录视图sys.server_principal中查看到,这个视图中还包含有每个服务器主体的一个SID。如果该主体是一个Windows登录账户,该SID就是Windows用来校验这个用户对Windows资源访问权限的SID。该视图包含有服务器角色、Windows用户组和映射到证书的登录账户,以及非对称密钥等信息行,这里不会对那些主体加以讨论。
注意: 不是所有登录到SQL Server的用户都能够查看sys.server_principals视图。在SQL Server 2005中,元数据是被全面保护起来的。除非我们具有很高的权限,或者被赋予服务器级别VIEW DEFINITION权限的用户,否则是无法查看这个视图的。
管理数据库安全性
数据库的所有者可以是登录账户名,前面已经从sys.databases视图中看到过,该视图有一列是拥有数据库登录账户的SID。登录账户名所拥有的唯一资源就是数据库。我们将会看到,数据库中所有的对象都被数据库用户所拥有。
一个主体所使用的SID取决于那个主体能够访问的数据库。每个数据库都有一个sys.database_principals目录视图,我们可以把它看作一个从登录用户名到特定数据库中用户的映射表。虽然一个登录用户名可以和一个数据库用户名相同,但是它们是完全不同的概念。下面的查询显示了AdventureWorks数据库中的用户与登录账户之间的映射,它还显示了每个数据库用户的默认架构(稍后讨论):
|
需要注意的是登录账户sue与这个数据库中的用户有着相同的名称。但不能保证sue能够访问的其他数据库会使用同样的用户名。登录账户名sa对应的用户名是dbo。dbo是一个特殊的用户名 ,登录账户sa、所有sysadmin角色里的成员账户和所有在sys.databases中列出的数据库的所有者账户都要用到它。在数据库中,它是用户而不是登录账户,并拥有对象。权限只能被赋予用户而不是登录账户。
前面的结果集也指出了在我的AdventureWorks数据库中的每一个用户的默认架构。在这个例子里,默认架构与用户名相同,但在下一节我们将看到并非所有的情况都是如此。
数据库与架构(Schema)
在ANSI SQL-92标准里,架构被定义为由单个用户所有的一组数据库对象,并构成一个单独的命名空间。一个命名空间就是一组不能重名对象。例如,两张表只有在不同
的架构下才能取相同的名字,也就是说,同一个架构下不能有两张名字一样的表。我们可以把架构看作对象的容器(在数据库工具的上下文中,架构也是指描述架构和数据库中对象的目录信息。在SQL Server Analysis Service中,架构是指对多维对象如多维数据集(cube)和维度(dimension)的描述)。
分离主体与架构
以前的版本,如SQL Server 2000,提供有CREATE SCHEMA语句,但是由于在用户和架构之间的隐式关系不能被更改或删除,所以它并没有任何有效的用途。实际上,这种关系是如此紧密以至于很多SQL Server 2000的用户认为用户和架构其实是相同的概念。每个用户都是一个与其同名的架构的所有者。如果我们创建一个用户例如sue,SQL Server会创建一个名为sue的架构作为sue的默认架构。权限被赋予用户,但是对象被放置在架构中。
在SQL Server 2000中,语句GRANT CREATE TABLE TO sue引用了用户sue。假定之后sue创建了一张表:
CREATE TABLE mytable (col1 varchar(20));
因为架构sue是用户sue的默认架构,所以这张表会被放入架构sue中。如果有另一个用户想要从这张表中取出数据,他可以使用下面的语句:
SELECT col1 FROM sue.mytable;
在这个语句中,sue就是包含有这个表的架构。
在新版本中SQL Server 2005打断了用户与架构之间的联系。一级和二级主体都可以拥有架构。虽然在SQL Server 2005中的每一个对象都为一个用户所有,但是我们决不需要根据所有者来引用对象,而是使用包含对象的架构来引用对象。另外,用户是不能被加到架构中的,架构包含的是对象而不是用户。为了向后兼容,当使用sp_adduser或sp_grantdbaccess存储过程来向一个数据库中添加用户时,SQL Server 2005同时会创建一个用户和一个架构,并将该架构作为新用户的默认架构。然而,我们应该习惯于使用新的DDL CREATE USER和CREATE SCHEMA。当我们创建一个用户时,可以选择指定一个默认的架构,但是默认情况下架构是dbo架构。
默认架构
当我们在SQL Server 2005中创建一个新的数据库时,其中包含有几个架构。这些架构包括对应SQL Server 2000中默认用户名的架构:dbo、INFORMATION_SCHEMA和guest。另外,每个数据库都有一个名为sys的架构,该架构提供了一种访问所有系统表和视图的方法。最后,每一个来自SQL Server 2000的预定义数据库角色在SQL Server 2005中都有一个架构。
当用户被创建时,可以指派给他一个可能存在也可能不存在的默认架构。在任何时候,一个用户最多只能有一个默认架构。前面提到,如果没有给一个用户指定默认架构,该用户的默认架构就是dbo。一个用户的默认架构可以用来在对象创建和对象引用期间进行名字解析。对后向兼容性来讲,这既是一个好的消息又是一个不好的消息。好的消息是如果我们从SQL Server 2000升级上来了一个数据库,其中很多对象都在dbo架构之下,那么我们的代码就能继续引用那些对象而不用显式地指定这个架构。坏的消息是对对象创建来讲,SQL Server将会尝试在dbo架构中而不是创建该表的用户所拥有的架构中创建对象。该用户也许没有在dbo架构下创建对象的权限,即使那是该用户的默认架构。为了避免混乱,在SQL Server 2005中,我们应该在所有的对象访问和对象管理时总是指定架构名称。
无论一个用户的默认架构是什么,SQL Server 2005对任何对象访问总是先检查sys架构。例如,如果一个用户Sue运行查询“select col1 from mytable ”并且Sue的默认架构是SueSchema,名字解析的过程如下:
1.寻找sys.table1。
2.寻找SueSchema.table1。
3.寻找dbo.mytable5。
注意当sysadmin角色中的一个登录账户创建一个只有一部分的名字时,架构总会是dbo。然而,一个sysadmin能够显式地指定一个替代架构并在该架构中创建一个对象。
为了在一个架构中创建一个对象,必须满足下列条件:
架构必须存在。
创建对象的用户必须有权限来创建对象(CREATE TABLE、CREATE VIEW、CREATE PROCEDURE等),或者是直接权限,或者是通过角色成员关系具备的权限。
创建对象的用户必须是架构的所有者,或者是拥有该架构的角色成员,或者是具有该架构修改(ALTER)权限的用户,或者是在整个数据库中具有修改任意架构(ALTER ANY SCHEMA)权限的用户。
第6章中当我们讨论元数据和表的时候,会再次查看架构和其中的对象。
译著:原文为“dbo是一个特殊的登录账户”,笔误。特此纠正。
| 回书目 上一节 下一节 |