所有权链接有一些局限性;它只适用于数据操作而不适用于动态SQL。进一步的,如果你穿过所有权限定访问对象,所有权链接就不可用。因此,这个预先的权限检查行为只能用于特定的情况。
SQL Server 2008具有使用一个执行上下文标识模块的能力,这样在模块中的语句就可以作为与调用用户相反的特殊用户来执行。这个方式,当调用用户仍然需要权限来执行模块时,SQL Server为模块内的语句对模块的执行上下文检查权限。你可以使用这个行动来克服所有权链接的一些缺点,因为它适用于模块内的所有语句。管理员如果想执行预先的权限检查的话可以使用执行上下文来完成这个工作。
现在当你定义用户定义的功能(除了在线的值为表的情况),存储过程和触发器时你可以使用EXECUTE AS 条件来指定SQL Server 使用哪个用户的权限来验证对由以下过程引用的对象和数据的访问:
以下是引用片段: CREATE PROCEDURE GetData(@Table varchar(40)) WITH EXECUTE AS ''User1'' |
SQL Server 提供了四个EXECUTE AS选项。
· EXECUTE AS CALLER 指定了在模块的调用者的安全上下文中执行的代码;没有发生身份模拟。调用者必须具有对所有引用的对象的访问权限。然而,SQL Server 只检查对所有权断链的权限,所以如果这个代码的所有者还拥有后台的对象,那么只会检查模块的执行权限。这是向后兼容性的默认执行上下文。
· EXECUTE AS ''user_name'' 指定了代码执行在指定用户的安全上下文下。如果你不想依赖于所有权链那么这是一个很好的选择。相反,你创建一个具有必要权限的用户来允许这个代码和创建定制的权限集合。
· EXECUTE AS SELF 是一个缩写符号,用于指定要创建或修改这个模块的用户的安全上下文。SQL Server 在内部保存和这个模块相关联的实际的用户名称,而不是“SELF”。
· EXECUTE AS OWNER 指定这个安全上下文是模块执行时的模块当前所有者的安全上下文。如果这个模块没有所有者,那么使用所包含的schema的所有者的上下文。当你想能够改变这个模块的所有者而不改变模块本身的时候这是一个很好的选择。
只要用户上下文使用EXECUTE AS选项进行变更,那么模块的创建者或更改者必须具有对指定的用户的IMPERSONATE权限。你不能从数据库中删除指定的用户,除非你将所有模块的执行上下文更改为其它的用户。
4.7 用户/schema分离
SQL Server 2000没有schema的概念,而在ANSI SQL-99规范中将schema定义为一个数据库对象的集合,由形成了对象的一个单独的命名空间的一个单独的主体所有。Schema是数据库对象的一个容器,例如表、视图、存储过程、函数、类型和触发器。它在.NET框架中更多的是作为一个命名空间函数,而XML是一种组织对象的方式,以便数据库可以重用对象名称,例如允许dbo.Customer和Fred.Customer存在于一个单独的数据库中,并将对象分类到不同的所有者下面。
注意你将需要使用目录视图例如sys.database_sys.principals、sys.schemas, sys.objects等等。因为老的sysobjects系统表不支持schemas,因此不能支持U/S分离。此外,老的目录视图是不被支持的,所以它们在SQL Server的未来版本中将被删除。
图9的上面部分显示了SQL Server 2000中schemas是怎样工作的。当一个管理员在数据库中创建一个用户Alice 时,SQL Server 会自动地创建一个隐藏在用户Alice之后的schema Alice。如果Alice 登陆到一个运行SQL Server而他没有所有权的服务器上创建Table1,那么表的实际名称是Alice.Table1。Alice 创建的其它