到SQL Server安全级别3的阶梯:主体和安全
此系列
本文是阶梯系列的一部分:通往SQLServer安全的阶梯
SQLServer拥有你所需要的一切来保护服务器和数据免受当今复杂的攻击。但在有效使用这些安全特性之前,需要了解所面临的威胁和一些基本的安全概念。第一个阶梯级别提供了一个基础,以便你可以充分利用SQLServer中的安全特性,而不浪费时间来保护你的数据免受特定威胁。
通常,通过将对象的权限分配给主体,可以在SQLServer中实现用户和对象安全性。但是什么是SQL Server主体?它得到什么许可?在这个阶梯级别,你将了解各种权限,这些权限可以通过权限来执行,并在SQLServer实例中访问安全对象。SQLServer中的一组重要的原则是角色,你将了解角色如何使管理安全远比作为唯一类型的主体的个人用户工作要容易得多。你还可以了解SQLServer中的安全对象,设置阶段以了解下一级的权限。
授权
在第2级中覆盖的身份验证只是访问数据库服务器中所有的GooDes的一部分。认证有点像有护照证明你是谁,但没有签证,你需要签证进入和移动全国各地。在这个级别,你将了解授权,以及它如何充当提供对数据库对象的访问的签证。
主体是可以访问SQL Server或其数据库中的一个或多个可安全对象的用户或进程。可保护对象(或仅可安全对象)是受保护的资源,只有某些人或进程可以查看或更改,例如表中的数据。权限允许主体获得对安全性的特定类型的访问。
为了继续护照的类比,当事人是护照持有人,照片中的人是护照持有人。可安全的是负责人想要访问的国家,许可是越过国境和参观的签证。
在安全的上下文中,主体是任何用户(人类类型)、用户组(称为SQLServer中的角色),或在进程中运行的代码,其可以请求访问安全对象并授予或拒绝访问该安全对象。所有Windows和SQLServer登录都是主体,以及它们映射到数据库内的用户。下面的列表显示了SQLServer中大多数更重要的主体的层次结构,从服务器范围的主体和跨越SQLServer实例的权限到数据库级主体:
窗口级主体
Windows域登录
Windows组
Windows本地登录
SQLServer级主体
SQLServer登录
映射到证书的SQL Server登录
映射到Windows登录的SQL Server登录
映射到非对称密钥的SQLServer登录
数据库级主体
应用角色
数据库角色
数据库用户
映射到证书的数据库用户
映射到Windows登录的数据库用户
映射到非对称密钥的数据库用户
公共角色
理解这个层次结构是很重要的,因为主体的范围部分地决定了授予它的权限的范围。例如,数据库用户可以仅在该数据库的上下文中授予它的权限。SQLServer级别的主体可以在整个服务器上具有权限,而Windows级别的主体可以具有超出SQL Server范围的权限,进入Windows和跨网络的本地实例。
注意,在前一个列表中,主体可以是一个登录(或用户)以及一个角色。SQLServer中的角色类似于Windows组。具有角色成员资格的用户继承分配给角色的权限。角色使安全管理变得更容易,因为你不需要为单个用户管理复杂的权限集。SQLServer支持以下类型的角色:
固定服务器角色:用于执行服务器级任务的SQLServer内置角色。
用户定义的服务器角色:你创建的自定义服务器角色,分配服务器级权限,并分配登录,以便它们继承服务器对象上的权限。
固定数据库角色:用于执行数据库任务和分配基本权限的内置角色。
用户定义的数据库角色:你创建的自定义数据库角色,将权限分配给用户,然后添加用户,以便用户继承数据库对象的权限。
可以将用户分配给多个角色。角色也可以嵌套,但是不要太过轻率,如果嵌套方案太复杂,你会遭受性能损失,并且它可以维护和排除恶梦。
固定服务器角色
固定服务器角色是SQLServer中的内置角色,你不能以任何方式更改它们,只能向它们添加登录。它们只存在于服务器级,用于执行管理任务。这里列出了SQLServer中的固定服务器角色,括号中的实际角色名称如下:
系统管理员(SysAdmin):在SQL Server实例中执行任何活动。一旦用户是系统管理员的成员,这个角色就包含了所有其他角色,它们不需要任何其他角色。系统管理员的成员可以做任何他们喜欢的事情,所以把会员资格限制在那些需要它的人身上是一个好主意,并且可以信任他们拥有无限的访问权限。
大容量插入管理员(BulkAdmin):执行批量插入语句以快速将数据获取到数据库中。
Database Creator(DbC造饰者):创建和更改数据库。
磁盘管理员(DISKADMIN):管理存储数据库的各种磁盘文件。
过程管理员(PersAdmin):管理在SQLServer中运行的进程。
服务器管理员(ServAdmin):配置服务器范围的设置。尽管名称与系统管理员相似,ServAdmin却是一个非常不同和更有限的角色。
安装管理员(StuuPADmin):安装复制并管理扩展过程。
安全管理员(SurvivAdmin):管理服务器的登录。
固定服务器角色通过允许将服务器任务划分为部分来提供灵活性和安全性。换句话说,如果他们只需要创建数据库,就不必让某人成为系统管理员。相反,让它们成为DbC造饰件的成员,它们拥有它们需要的所有权限。
你可以通过使用Management Studio或Transact-SQL将登录名分配给固定服务器角色。使用Management Studio,执行以下步骤:
提示:
这个阶梯2级的代码创建了黄玉登录。如果你没有创建该登录,请自由运行该代码来创建它,或者使用第2级中讨论的技术创建自己的登录。如果执行后者,则根据需要调整步骤以使用该登录。
展开Management Studio中对象Explorer的安全部分,以显示登录列表。
右键单击黄玉登录,并从弹出菜单中选择属性。
在“登录属性”对话框中,选择“服务器角色”页。这列出了所有可用的服务器角色,并使用复选框将登录添加到每个服务器角色。请注意,像所有登录一样,黄玉已经成为公众角色的一员。
将登录名分配给DbC造饰件和DISKADMIN角色。图3.1显示了登录黄玉的对话框。
图3.1。将登录黄玉分配给DbC造饰件和DISKADMIN固定服务器角色。
单击“确定”保存更改。
或者,可以使用对象资源管理器中的安全节点下的服务器角色节点向角色添加登录。向安全管理服务器角色添加黄玉:
在对象资源管理器中的安全节点下展开服务器角色节点。
右击对象资源管理器中的SuffigyAdmin服务器角色并选择属性。这将打开“服务器角色属性”对话框。
单击对话框右下角附近的“添加”按钮,打开“选择登录”对话框。你可以键入黄玉并单击“检查名称”,或者单击“浏览”按钮获得登录列表。一旦进入黄玉,对话框看起来像图3.2。
图3.2。选择黄玉以添加到服务器角色。
单击“确定”向服务器角色添加黄玉。“服务器角色属性”对话框如图3.3所示。
图3.3。将TopAz添加到SuffigyAdmin服务器角色。
单击“确定”保存更改。
另一种向服务器角色添加登录的方法是使用Transact-SQL,使用SPAdAdSrVoReMeMever系统存储过程。下面的代码将现有登录黄玉添加到系统管理员角色:
EXEC sp_addsrvrolemember 'Topaz','sysadmin';
清单3.1:将登录添加到服务器角色的代码。
通过运行两个存储过程SPSPHelpSvPr角色和SPHelpRelsVReMeMeNever,可以找到有关固定服务器角色的信息。如果将服务器角色的有效名称传递给SPHelpRSvVal角色,它将显示该角色的描述;否则,它将显示所有服务器角色。图3.4显示了在Management Studio中执行的系统存储过程,以显示SuffigyAdmin角色及其当前成员资格的描述。
图3.4。使用系统存储过程获取有关服务器角色的信息。
用户定义的服务器角色
SQL Server 2012中期待已久的安全特性是用户定义的服务器角色。SQLServer对数据库级权限有很长的灵活的用户定义的数据库角色(稍后将在本层中了解),但是使用自定义服务器角色,你最终可以得到具有服务器级权限的颗粒状。
在旧版本的SQLServer中,向用户授予某种权限的唯一方法是将它们分配给内置的固定服务器角色,该角色通常具有太多权限。让每个人成为一个系统管理员是一个可怕但常见的做法,尤其是有问题的,因为你不能否认一个系统管理员任何事情。这违反了最大特权的原则,但往往是一种现实的需要。SQLServer 2005和更高版本使这些更加粒度化,允许你为用户分配任何特定的服务器级权限,但缺乏将这些权限分组到服务器角色的能力。
SQL Server 2012解决了它对用户定义的服务器角色的支持。创建新的服务器角色与使用CREATE Server角色语句一样简单:
CREATE SERVER ROLE LimitedDBA;
清单3.2:创建新服务器角色的代码。
然后,你可以授予和拒绝你想要的任何服务器级权限的角色。下面的代码授予控制服务器对新角色的许可,类似于授予系统管理员权限,然后拒绝了一些权限来缩小服务器角色成员的权限。这是授予特定于组特定权限的用户的非常灵活的方式。
USE master;
GO
-- Grant the role virtual sysadmin permissionsGRANT CONTROL SERVER TO LimitedDBA;
-- And take some permissions awayDENYALTERANY LOGIN TO LimitedDBA;DENYALTERANY SERVER AUDIT TO LimitedDBA;DENYALTERANY SERVER ROLE TO LimitedDBA;DENYCREATE SERVER ROLE TO LimitedDBA; -- Covered by ALTER ANY SERVER ROLEDENY UNSAFE ASSEMBLY TO LimitedDBA;
清单3.3:添加和拒绝服务器角色权限的代码。
为了测试这个角色,清单3-4中的代码在一个名为马拉松的机器上创建了一个与Windows组、DBA相关联的登录,并将新的登录添加到LimeDeDBA角色。
提示:
在运行此代码之前,必须在Windows的本地实例上存在DBA组。你可以通过进入控制面板的计算机管理小程序,扩展系统工具和本地用户和组节点,并将其添加到组节点中来创建它。此外,将机器名称从马拉松改为本地机器。
-- Create a login for DBAs Windows groupCREATE LOGIN [Marathon\DBAs]FROM WINDOWS;
-- Add to the server roleALTER SERVER ROLE LimitedDBA ADD MEMBER [Marathon\DBAs];
清单3.4:创建登录并将其添加到服务器角色的代码。
清单3.5中的代码然后创建一个SQLServer登录卡,在SQL Server实例中没有任何权限。然后,代码尝试在CAROL的安全上下文中需要服务器级别权限的各种操作:创建另一个登录,查看系统信息,并创建另一个服务器角色。所有这些操作都失败了,如图3.5所示,因为CAROL主体没有执行这些操作的权限。
-- Create carol loginCREATE LOGIN carol WITH PASSWORD ='crolPWD123%%%';
EXECUTEAS LOGIN ='carol';-- Verify user contextPRINT suser_sname();-- Can Carol alter logins?CREATE LOGIN donkiely WITH PASSWORD ='G@Sm3aIKU3HA#fW^MNyA'; -- No-- Other server-level permissions?SELECT*FROM sys.dm_exec_cached_plans; -- No, requires VIEW USER STATECREATE SERVER ROLE CarolRole; -- NoREVERT;
清单3.5:创建登录和测试以查看它是否具有特定权限的代码。
提示:
此代码不检查SQLServer实例中是否存在现有的CAROL登录。如果存在,则创建登录语句将失败。在这种情况下,跳过该语句。
图3.5。失败,因为CAROL没有权限。
接下来,代码将CAROL添加到新的LimeDeDBA用户定义的服务器角色中,并再次尝试执行相同的操作。如图3.6所示,此时CAROL能够获得系统信息(选择动作),因为该权限是通过控制服务器权限授予的。但CAROL仍然无法创建登录或服务器角色,因为这些权限是从LimeDeDBA角色明确拒绝的。
ALTER SERVER ROLE LimitedDBA ADD MEMBER carol;
-- Now does Carol have permissions?EXECUTEAS LOGIN ='carol';CREATE LOGIN donkiely WITH PASSWORD ='G@Sm3aIKU3HA#fW^MNyA'; -- Still not possibleSELECT*FROM sys.dm_exec_cached_plans; -- Yes, CONTROL SERVER covers VIEW USER STATECREATE SERVER ROLE CarolRole; -- Not possibleREVERT;
清单3.6:再次测试服务器角色成员是否具有特定权限的代码。
图3.6。通过LimitedDBA的部分权限的服务器级操作的结果。
为了查看所有可以授予和拒绝服务器角色的可用服务器级权限,请执行以下代码。图3.7显示了结果。
SELECT*FROM sys.fn_builtin_permissions('SERVER')
ORDERBY permission_name;
清单3.7:查看所有可用的服务器级权限的代码。
图3.7。服务器级别权限的部分列表。
你可以创建用户定义的服务器角色,以授予用户和组一个非常特定的权限集,它们需要完成自己的任务,而不再需要。这比SQLServer的早期版本更灵活,使得SQL Server 2012的安全管理变得更容易,更容易的管理必然意味着更安全的服务器。
固定数据库角色
固定数据库角色存在于数据库级别,而不是服务器级别,并且仅在该数据库内控制授权。每个数据库都有自己的固定数据库角色集合,因此你可以单独配置每个数据库中的角色。固定数据库角色类似于固定服务器角色,因为它们不能被删除、修改或更改,但可以将数据库用户和用户定义的角色添加为成员。固定数据库的角色是:
可以添加或删除数据库中的Windows登录和组和SQLServer登录。
可以备份数据库。
DbjDATaReaDe:可以查看数据库中所有用户表中的任何数据。
DbjDATAWrWrn:可以在数据库中的所有用户表中添加、更改或删除数据。
dBdDLADMIN:可以在数据库中添加、修改或删除对象。(DDL代表数据定义语言,对数据库进行结构更改的Transact-SQL命令集)。
数据库无法查看数据库中的任何数据。
无法更改数据库中的任何数据。
DbWORKBOOST:可以执行所有数据库角色的活动以及维护和配置活动。这个角色包括所有其他角色,所以它本质上是这个数据库的管理员。
可以管理数据库中的角色成员资格和语句和对象权限。
固定数据库角色可以简化数据库中的权限分配。例如,假设你希望允许用户访问特定数据库,以便只备份它。你不希望用户能够读取数据,只是备份它。你可以通过让用户成为dByBuffuPuxor和dByDyDATaReADER角色的成员来轻松实现这一点。使用SPHELPROLE和SPHELPROMLMENS系统存储过程查看数据库角色的信息。
公共角色与宾客
有几个特殊的原则需要提及。你不可能以任何有意义的方式使用这些原则,但是它们确实影响安全性,所以你需要知道它们是什么。
公共角色是一个不可丢弃的特殊服务器角色。每个数据库用户都属于这个公共角色,因此你不需要为它分配用户、组或角色。每个SQLServer数据库都包含公共角色,包括主、MSDB、TEMPDB和模型。但是,可以根据安全需要指定或限制公共角色的权限。在公共角色中要考虑的重要事项是授予公共应用程序的权限给所有数据库用户。
提示:
通常,你希望限制授予公共角色的权限,因为授予每个人的权限很少导致安全数据库。
访客用户存在于每个数据库中,包括主数据库和模型等系统数据库。作为用户,它继承公共角色的权限。当服务器登录未映射到特定数据库中的用户时,它就会发挥作用。默认情况下,客户机用户没有权限,但你可以授予访问数据库对象并在数据库中执行操作的权限。正如你所期望的,这是一个非常危险的事情,在数据库服务器的精心设计的安全方案中很少需要这样做,并且你应该避免向该用户分配权限。虽然无法删除此用户,但应使用用户清单3.8中的代码撤销其连接权限,从而禁用用户数据库。
USE Northwind;
GO
REVOKE CONNECT FROM guest;
GO
清单3.8:通过撤销其连接权限来禁用用户数据库中的客户机用户的代码。
提示:
不要禁用系统数据库中的访客用户,这可能会导致你不想处理的问题!这些数据库需要客户机用户提供各种功能。
DBO用户与模式
DBO是映射到SyAdmin固定服务器角色的每个数据库内的一个特殊用户帐户。这意味着,如果你是系统管理员角色的成员,并且在任何数据库中创建对象,那么该对象的所有者将是DBO,而不是你。你不能删除DBO用户,它只映射到系统管理员,而不是数据库所有者(dBWORKBOOST)。这可能会让人困惑,因为DBO用户与数据库所有者角色无关。
每个数据库还具有由DBO用户拥有的DBO模式,并且是DBO用户的默认模式。因此,当你访问数据库作为一个系统助理并创建一个对象而不指定一个模式时,它的两部分名称将是DBO.ObjtNeX。如果没有指定架构名,DBO模式也是任何其他用户访问数据时的第二默认模式。如果用户乔试图访问一个名为“销售”的表,SQLServer将首先检查用户乔的默认模式中是否有销售表,如果没有,它将检查DBO模式中是否有销售表。只有在任一模式中不存在销售时,才会产生无法找到对象的错误。最好的做法是总是为访问的每个对象指定一个模式名。
用户定义的数据库角色
数据库角色不限于你可以创建自己角色的预定义角色。用户可以定义两种类型的数据库角色:
标准角色:使用此角色简化对用户组的权限分配。你可以嵌套固定的数据库角色或其他用户定义的角色,并将用户分配给角色,在这种情况下,它们继承角色的权限。
应用程序角色:应用程序使用此角色允许应用程序或连接登录到数据库,并通过提供角色名和密码来激活应用程序角色。你不能以其他角色的方式将用户添加到应用程序角色,一旦激活,应用程序角色的权限将应用于连接的持续时间。用户可能拥有的任何权限都被挂起,并且只检查应用程序角色的权限。
提示:
可以将用户定义的角色添加到固定数据库角色中,这与将用户添加到固定数据库角色的方式相同:通过固定数据库角色的属性对话框。
安全对象
可保护对象是可以控制访问的受保护资源。通常它是一个物理的东西,或者至少是像数字物体一样物理的东西!但安全性也可以是一种操作,即对数据库或SQL Server实例进行某种更改的能力。例如,管理员可以授予主体获取对象所有权的能力。授予该权限不会立即改变对象的所有权;它只是赋予主体在将来某一时间完成该操作的能力。
图3.8显示了SQLServer实例中的大多数可安全对象。服务器级安全对象具有最广泛的范围,涵盖所有SQLServer,包括影响主体对所有数据库进行更改的能力的权限。数据库范围包含特定数据库中的所有对象,例如用于管理用户以及创建加密密钥的对象。架构范围包括架构内的所有对象,本质上是数据库的数据结构,包括表和它们的数据。数据库可以包含许多模式,并且每个数据库都可以包含数据库对象的全组子集。使架构强大的是,你可以指派和拒绝架构上的权限,这些权限应用于架构包含的所有对象。
图3.8。SQLServer中的安全对象。箭头显示了一个范围如何在对象层次结构中包含较小的范围。
重要的是要理解,在服务器级别授予权限通常意味着在较小范围内的权限。例如,授予数据库级权限可能意味着主体对数据库架构中的一个或全部模式中的对象具有隐含的权限。
总结
在SQLServer安全性的这个级别中,你了解了SQLServer实例及其数据库中的授权的第一部分、主体和可安全对象。在下一个级别,你将了解权限,当授予可安全对象上的主体时,授予或带走主体对对象进行某种操作的能力。通过这种理解,你将能够有效地使用SQL Server中的认证和授权的粒度性质,从而对数据库资产进行严格控制,同时允许授权的用户和进程完成其工作。