• 【译】第五篇 SQL Server安全架构和安全


    本篇文章是SQL Server安全系列的第五篇,详细内容请参考原文


    架构本质上是一个数据库对象,其他对象的一个容器,在复杂的数据库中它能够很容易的管理各组对象。架构具有重要的安全功能。在这一篇你会学习如何给主体访问一组对象,通过给架构分配权限而不是单个表、代码模块和其他对象。你还会了解用户与架构分离的好处,以及如何提高对象安全性,如何为用户、组使用默认架构来简化对象访问管理和安全性。
    Schemas with Roles and Permissions
    The relationship of schemas with roles and permissions is an important security concept in SQL Server.一个完全合格的数据库对象名称由四部分组成:

    server.database.schema.object

    通常使用架构和对象名称来引用当前数据库下的对象。一个架构是一个对象集合,如表、代码模块,如图5.1所示。这种组织结构简化了用户管理,特别是当你需要改变对象的所有权时。但更重要的是为了安全,它简化了权限管理。

    图5.1 一个包含数据库对象的示例架构
    你可以将权限分配给架构应用于架构下的所有对象。例如,如果你将DogSchema架构的SELECT权限授予给一个主体,这个主体将可以查询DogSchema架构下的所有表格。和所有用户定义的数据库对象一样,架构有一个所有者可以完全控制对象。
    在架构中单独设置对象权限通常是一个选项,但如果你已经将数据库中的架构设计好,在某些功能类型的数据库中,你可以在架构上设置权限,并将其应用到对象。最棒的是,你在架构上分配的权限会自动应用到你添加到架构中的任何对象。继续SELECT的例子,如果一年后你添加表DogTable4到架构DogSchema,所有对架构有SELECT权限的主体都能自动的SELECT新表。
    多个用户和角色可以具有相同的默认架构,如果主体没有默认架构,SQL Server会尝试在dbo架构下查找或创建对象。
    现在,你将看到如何使用架构来分配对象的权限。使用以下步骤将Purchasing架构的查询、更新、删除、插入权限授予给DataEntry用户自定义角色。在第4篇创建了DataEntry角色;如果你没有创建,请执行代码5.1

    USE AdventureWorks2012;
    GO
    CREATE ROLE DataEntry AUTHORIZATION dbo;

    代码5.1 在AdventureWorks2012数据库创建DataEntry角色
    然后按照下面步骤在SSMS使用图形工具来分配所需的权限
    1、对象资源管理器->数据库->AdventureWorks2012->安全性->角色->数据库角色->DataEntry
    2、右击DataEntry,弹出菜单选择属性。在数据库角色属性对话框选择安全对象。如果你遵循第4篇的步骤,你应该可以看到之前为角色分配过权限的表和存储过程
    3、点击“搜索”按钮打开“添加对象”对话框
    4、在添加对象对话框,选择“特定类型的所有对象”选项,如图5.2所示。点击确定,打开“选择对象类型”对话框

    图5.2 添加对象
    5、在“选择对象类型”对话框中,向下滚动到“架构”项目,然后选择旁边的复选框。对话框应该看起来像图5.3。单击“确定”以保存选择并关闭对话框

    图5.3 选择对象类型
    6、返回到数据库角色属性对话框中,向下滚动安全对象列表然后点击Purchasing架构。页面的下部显示了可用的权限
    7、显示页签为Purchasing架构勾选删除、插入、选择、更新授予复选框。数据库角色属性对话框如5.4所示

    图5.4 设置对Purchasing架构的访问权限
    到此DataEntry角色下的所有成员对AdventureWorks2012库Purchasing架构下的所有表都有选择、更新、删除和插入权限。只有当该角色的成员被拒绝任何权限时,才会出现异常。DENY阻止了他们通过角色继承的权限。
    当然,你也可以使用TSQL脚本将架构上的权限授予给角色

    GRANT DELETE ON SCHEMA::Purchasing TO DataEntry;
    GRANT INSERT ON SCHEMA::Purchasing TO DataEntry;
    GRANT SELECT ON SCHEMA::Purchasing TO DataEntry;
    GRANT UPDATE ON SCHEMA::Purchasing TO DataEntry;
    GO

    代码5.2 给Purchasing架构授权
    这些技术表明你可以创建不同的架构,在每个架构中放置不同的对象,然后在架构上分配权限。这节省了单个表上分配权限的工作。如果你授予权限给角色,正如我们对DataEntry角色的操作,你可以高效地对许多主体分配权限。这让你分割数据库,简化你的设计并实现数据库的安全性。
    默认架构
    在SQL-99规范定义,架构本质上是一个数据库的对象容器。它可以由一个主体拥有,如图5.5所示(同图5.1)。使用架构作为数据库对象容器的好处之一是:当Carol离开公司时,不需要改变Carol拥有的数百或数千个对象的所有权,管理员只需要改变这些架构的所有权,每个可能有成千上万的对象。这种方法是更简洁、更容易、更安全。

    图5.5 Carol拥有的DogSchema架构
    SQL Server允许你为用户和组分配默认的架构。设置默认架构是一种方便,并且具有一些重要的操作好处。特别是,当命名和访问对象时它消除了一些歧义。
    用户默认架构
    SQL Server不会自动创建具有相同名称的架构当你创建一个用户。你必须显式地创建一个架构,分配架构所有者,然后创建和添加对象到该架构。你可以(通常应该)为用户分配一个默认架构,这样所有用户创建的对象,如果没有显式地分配给另一个架构,都会成为默认架构的一部分。
    本篇中的代码显示了所有的操作,当用户没有一个设置默认架构时会发生什么情况。我会解释每一步会发生什么,但你可能想独自执行代码,以更好地了解发生了什么事。当然,你自己试试吧!如果你想看看发生了什么,执行每一个代码块。
    代码5.3做了演示所需的一些设置。你可能已经创建了第三篇的登录名carol,所以如果存在登录名carol首先删除它。创建DefaultSchema数据库并设置为当前数据库,接着创建登录名carol,并映射到数据库用户,并授予它创建表的权限。然后,它将执行上下文更改为用户carol。

    IF suser_sid('carol') IS NOT NULL DROP LOGIN carol;
    GO
    CREATE DATABASE DefaultSchema;
    GO
    USE DefaultSchema;
    GO
    CREATE LOGIN carol WITH PASSWORD = 'crolPWD123%%%';
    CREATE USER carol FOR LOGIN carol;
    GRANT CREATE TABLE TO carol;--user
    
    EXECUTE AS LOGIN = 'carol';
    GO

    代码5.3 创建DefaultSchema数据库并设置carol用户
    接下来的代码试图创建一个新表table1,如代码5.4所示。但之前的代码创建carol用户时并没有给它分配默认架构。SQL Server尝试使用dbo架构,这是默认的回退架构。但carol没有数据库的所有权,所以它不能在dbo架构中创建对象。

    CREATE TABLE table1 (tID int);

    代码5.4 尝试以carol上下文创建表
    因为carol没有必要的权限,创建表语句失败并返回错误信息。
    指定的架构名称 "dbo" 不存在,或者您没有使用该名称的权限。
    代码5.5REVERT到原来的管理员登录,然后创建一个架构,并将架构所有者设为carol用户。你会在SQL Server中看到很多AUTHORIZATION子句,因为它可以让你在创建或更改一个对象时分配所有权。

    REVERT;
    CREATE SCHEMA DogSchema AUTHORIZATION carol;

    代码5.5 创建DogSchema架构
    再次更改执行上下文为carol,然后试图再创建表table1,但它失败了!现在的问题是,用户拥有一个架构并不意味着它是用户的默认架构。一个用户可以拥有成百上千个架构,SQL Server没有责任挑选一个作为默认架构。最终在创建表的时候显示的包含架构才能通过。代码5.6中明确地在DogSchema架构创建表

    EXECUTE AS LOGIN = 'carol';
    GO
    CREATE TABLE DogSchema.table1 (tID int);

    代码5.6 创建带有显示架构的表
    如果DogSchema架构存在,第二种尝试创建表的方式,就是在创建用户的时候分配默认架构,或者后期修改用户默认架构。如代码5.7所示

    CREATE USER carol FOR LOGIN carol WITH DEFAULT_SCHEMA = DogSchema;
    -- or
    ALTER USER carol WITH DEFAULT_SCHEMA = DogSchema;--测试可以在carol身份下执行

    代码5.7 给用户carol设置默认架构
    如果你执行ALTER USER语句为carol设置默认架构,然后你可以执行代码5.8成功创建表而不需指定架构。创建表的语句将创建一个DogSchema.table2表,因为DogSchema是carol的默认架构。

    EXECUTE AS LOGIN = 'carol';
    GO
    CREATE TABLE table2 (tID int);
    GO
    SELECT * FROM table2;
    REVERT;

    代码5.8 创建表table2不需指定架构
    另一个有趣的现象是,当你使用REVERT语句返回到自己的安全上下文,你不能执行代码5.9。除非你设置自己的默认架构为DogSchema,否则SQL Server将查找dbo.table2

    SELECT * FROM table2;

    代码5.9 在carol安全上下文之外运行会出错
    你需要显式地使用架构来识别你想从中读取数据的表,如代码5.10。本代码成功,并返回DogSchema.table2中的内容。

    SELECT * FROM DogSchema.table2;

    代码5.10 指定架构执行SELECT语句
    SQL Server用户与架构分离可以严格控制你的数据库和应用程序的安全结构。这使得它更容易管理一个数据库和SQL Server。你不需要为每一个对象设置成dbo用户所有者,这在2005之前版本很常见。
    下面增加部分测试代码(原文不含)

    /***使用sysadmin角色成员创建登录名caro2并映射到DefaultSchema库下的用户caro2,给用户caro2赋予创建表的权限***/
    USE DefaultSchema;
    GO
    --step1:创建创建名、用户、分配权限
    CREATE LOGIN caro2 WITH PASSWORD = 'crolPWD123%%%';
    CREATE USER caro2 FOR LOGIN caro2;--默认架构为dbo
    GRANT CREATE TABLE TO caro2;--user
    --step2:切换到caro2上下文
    EXECUTE AS LOGIN = 'caro2';
    SELECT SUSER_NAME()
    CREATE TABLE table11 (tID int);--指定的架构名称 "dbo" 不存在,或者您没有使用该名称的权限。
    ALTER USER caro2 WITH DEFAULT_SCHEMA = DogSchema;--修改默认架构为DogSchema
    CREATE TABLE table12 (tID int)--指定的架构名称 "DogSchema" 不存在,或者您没有使用该名称的权限。
    
    --step3:授予权限
    revert
    grant alter on schema::DogSchema to caro2
    --重新执行step2,正常
    drop table table11
    drop table table12
    --step4:收回权限
    revert
    revoke alter on schema::DogSchema from caro2--恢复成刚创建时的默认权限,此时创建表失败
    
    --step5:收回权限后再以caro2身份创建表
    EXECUTE AS LOGIN = 'caro2';
    SELECT SUSER_NAME()
    CREATE TABLE table13 (tID int)--指定的架构名称 "DogSchema" 不存在,或者您没有使用该名称的权限。
    --step6:更改架构所有者
    REVERT
    ALTER AUTHORIZATION ON SCHEMA::[DogSchema] TO [caro2]
    
    --重新执行step5,正常
    select * from table13
    drop table table13
    
    --stpe7:测试原架构所有者
    REVERT
    EXECUTE AS LOGIN = 'carol';--此时carol的权限同step1仅有create table权限
    SELECT SUSER_NAME()
    CREATE TABLE table14 (tID int)--指定的架构名称 "DogSchema" 不存在,或者您没有使用该名称的权限。
    
    --恢复原架构所有者,删除测试对象
    REVERT
    ALTER AUTHORIZATION ON SCHEMA::[DogSchema] TO [carol]
    drop user caro2
    drop login caro2
    View Code

    组默认架构
    用户的默认架构,在SQL Server 2005引进,解决了查询、创建对象以及其他操作在正确的架构下使用正确的对象。但这些默认架构的存在一个问题,你可以很容易的在数据库中创建大量的架构。Windows组的默认架构,在SQL Server 2012引进,解决了这些问题。
    使用下面的步骤来探索用户默认架构的潜在问题。步骤假定本地Windows有一个DBAs组,并且ClearFile用户是DBAs组中的成员。你需要更改示例代码中的机器名称。最后,DefaultSchema数据库应该已经存在。
    1、修改当前数据库为DefaultSchema,代码5.11首先创建一个Windows组的登录名,然后创建DataAdmins用户映射到此登录名,接着创建DBAs角色并添加DataAdmins用户到角色中。

    USE DefaultSchema
    GO
    CREATE LOGIN [USER-67NP5R8LGKDBAs] FROM WINDOWS;
    CREATE USER DataAdmins FROM LOGIN [USER-67NP5R8LGKDBAs];
    CREATE ROLE DBAs;
    ALTER ROLE DBAs ADD MEMBER DataAdmins;

    代码5.11 创建登录名、用户、角色
    2、授予对DogSchema架构的创建表和控制权限给DBAs角色

    GRANT CREATE TABLE TO DBAs;
    GRANT CONTROL ON SCHEMA::DogSchema TO DBAs;

    代码5.12 授予权限给DBAs角色
    3、用ClearFile身份运行另一个SSMS。在Windows启动菜单按下SHIFT键,并且右击SSMS。在弹出的菜单中选择以其他用户身份运行,键入ClearFile的用户名和密码
    4、在连接到服务器对话框使用Windows身份验证,用户名为ClearFile,如图5.6所示。点击连接,就以ClearFile身份运行SSMS

    图5.6 以ClearFile身份登录SSMS
    5、在刚打开的SSMS新建查询,可用数据库切换到DefaultSchema数据库
    6、执行代码5.13,成功创建了表table1,但它的架构是什么呢?

    CREATE TABLE table1 (tID int)

    代码5.13 使用ClearFile创建表table1
    7、对象资源管理器下DefaultSchema数据库展开表、用户、架构。如图5.7所示,前面语句创建的表叫USER-67NP5R8LGKClearFile.table1,数据库用户USER-67NP5R8LGKClearFile,架构USER-67NP5R8LGKClearFile

    图5.7 没有默认架构时创建表的结果
    8、回到你以管理员登录的SSMS,在对象资源管理器下按顺序删除刚才创建的表、架构和用户
    9、还是在原SSMS,执行代码5.14给用户DataAdmins设置默认架构DogSchema

    ALTER USER DataAdmins WITH DEFAULT_SCHEMA = DogSchema;

    代码5.14 为DataAdmins用户认置默认架构
    10、返回到ClearFile登录的SSMS,执行代码5.15创建新表table3。这次代码创建的表叫做DogSchema.table3,并且没有添加ClearFile数据库用户,也没有添加ClearFile架构

    CREATE TABLE table3 (tID int)

    代码5.15 创建表table3
    你也可以在数据库用户对话框设置默认架构,如图5.8所示

    图5.8 使用数据库用户对话框设置默认架构
    SQL Server 2012增加了给组设定默认架构的功能,类似于给用户设定默认架构解决问题,使安全管理更容易。对于同样的原因,你创建没有任何权限的用户,然后将它们添加到需要的权限组中,你可以为组指定默认架构,而不是每个用户。与用户一样,你可以通过create user或者alter user指定默认架构。

    -- Clean up
    USE master;
    GO
    IF SUSER_SID('carol') IS NOT NULL DROP LOGIN carol;
    IF SUSER_SID('caro2') IS NOT NULL DROP LOGIN caro2;
    IF SUSER_SID('USER-67NP5R8LGKDBAs') IS NOT NULL DROP LOGIN [USER-67NP5R8LGKDBAs];
    IF DB_ID('DefaultSchema') IS NOT NULL DROP DATABASE DefaultSchema;
    GO
    View Code

    总结
    架构在SQL Server管理数据库对象上是一个很好的特征,还提供了重要的安全功能。通过在一个架构上设置权限,而不是它包含的单个对象,你可以更轻松地管理数据库的权限。这是特别重要的,当你有很多主体需要授予权限时。
    一定要给用户和组分配默认架构,这样就可以避免意外的对象创建,同时简化代码和数据库维护。随着对组设置默认架构的能力,微软充实了架构安全效益。

  • 相关阅读:
    [Go] 解决空接口 interface{} cannot use (type []string) as type []interface {}
    [Linux] 脚本中的set -e有什么作用
    [Go] 解决go test 时 testing: warning: no tests to run
    [Go] go for range循环map是无序的 变成有序
    [Linux] ubuntu 32位 i686 安装docker
    [Git] git checkout 恢复未add的修改文件
    [MySQL] in 子查询出现DEPENDENT SUBQUERY问题
    [MySQL] group by 聚合函数的原理和聚合限制原因SELECT list is not in GROUP BY clause and contains nonaggregated column
    [MySQL]mysql的ANY_VALUE()函数 解决 ONLY_FULL_GROUP_BY 模式
    [Go] GODEBUG=inittrace=1 查看所有执行的init函数
  • 原文地址:https://www.cnblogs.com/Uest/p/4708307.html
Copyright © 2020-2023  润新知