Security8:EXECUTE AS 模拟权限

用户可以模拟其他用户或登陆的权限来执行查询,并且在查看用户和登录的权限时,结果会受到模拟上下文的影响。当执行EXECUTE AS命令时,原始用户的安全上下文会进行切换,除了ORIGINAL_LOGIN之外,其他函数都会返回模拟上下文的Login和User信息。

一,指定Session的安全上下文

默认情况下,一个会话在用户登陆时开始,在用户退出时结束,用户的权限决定了用户的操作。当用户使用EXECUTE AS 命令时,当前用户的权限切换到制定的用户或登陆的安全上下文,以模拟对象的权限来执行操作。EXECUTE AS 命令用于设置会话的执行上下文:

{ EXEC | EXECUTE } AS { LOGIN | USER } = 'domain\name' | CALLER
...
REVERT;

把执行上下文切换到指定的Login 或User,参数CALLER 只用于模块内部,以模块调用者的安全上下文来执行。

要结束权限模拟,可以执行命令 REVERT,该命令用于恢复当前用户的原始执行上下文。

当执行EXECUTE AS 命令之后,用户的安全上下文会被切换为指定的用户。ORIGINAL_LOGIN() 返回最原始的Login名称,不受上下文切换的影响:

ORIGINAL_LOGIN( ) 

其他返回用户和Login的函数,都是基于当前上下文的。比如,SESSION_USER返回当前安全上下文的用户名称,如果该函数在EXECUTE AS 命令之后被调用,那么上下文被切换,SESSION_USER返回模拟上下文的用户名称:

SESSION_USER 

二,指定模块的安全上下文

在SQL Server中,可以定义用户自定义模块(函数(内联表值函数除外)、存储过程、queue和触发器)的执行上下文,通过指定这些执行模块的上下文,可以控制数据库引擎使用哪个用户帐户来验证对模块引用的对象的权限。当需要严格限制用户的权限时,可以仅仅授予用户执行模块本身的权限,而不必授予他们访问模块内部引用的对象的权限。这需要通过EXECUTE AS 子句来实现,默认值是CALLER,也就是说,使用模块调用者的安全上下文来访问模块和模块内部引用的对象:

WITH EXECUTE AS { CALLER | SELF | OWNER | 'user_name' }  

参数注释

  • CALLER:除了Queue模块之外,CALLER是所有模块的默认值,指定模块内的语句在模块调用者的上下文中执行,模块的调用者不仅要有调用模块的权限,还要有访问被模块引用的对象的权限,也就是说,执行模块的用户不仅需要有适当的权限来执行模块本身,而且对模块引用的任何数据库对象也必须具有适当的权限。
  • SELF:SELF是Queue模块的默认值,EXECUTE AS SELF 等效于 EXECUTE AS user_name,其中指定的user_name是创建或更改模块的人,指定以模块的创建者或修改者的安全上下文来执行模块本身和访问模块内部引用的对象。
  • OWNER:指定模块内的语句在模块当前所有者的上下文中执行。如果模块没有指定的所有者,则使用模块schema的所有者的上下文。
  • user_name ':指定模块内的语句在 user_name 所在的上下文中执行,并且模块内任何对象的权限都根据 user_name 进行验证。不能为具有服务器范围或登录触发器的 DDL 触发器指定 user_name,请改用 login_name。

数据库对象的Owner可以通过命令ALTER AUTHORIZATION来修改,常见的class_type是:OBJECT、ROLE、SCHEMA :

ALTER AUTHORIZATION    
ON [ <class_type>:: ] entity_name    
TO { principal_name | SCHEMA OWNER } 

通过指定模块的执行上下文,你可以控制数据库引擎使用哪个用户的安全上下文来验证被模块引用的对象的权限。也就是说,通过使用模块的EXECUTE AS 子句,可以把执行用户自定义模块的权限分为两部分:执行模块的权限,以及访问被模块引用的对象的权限。一个用户可以只授予执行模块的权限,而不用授予访问被模块引用的对象的权限。对于这种情况,模块的EXECUTE AS 子句必须指定一个用户,模块的调用者通过模拟该用户的上下文来访问被模块引用的对象。

对于模块的EXECUTE AS 子句,其指定的执行上下文的用户 ID 存储在元数据中,可以通过 sys.sql_modules 或 sys.service_queues视图的列 execute_as_principal_id来查看,该字段有三种类型的值:

  • NULL: 默认设置,EXECUTE AS CALLER
  • -2:EXECUTE AS OWNER
  • ID 值:特定的Principal ID,通过子句EXECUTE AS SELF 或 EXECUTE AS <principal>来指定

模块的调用者必须具有调用(EXECUTE)模块的权限,授予用户调用(EXECUTE)模块的权限,不代表用户具有访问被模块引用的对象的权限。用户只有同时具备调用模块的权限和访问被模块引用对象的权限,才能成功执行模块。

CREATE PROCEDURE dbo.usp_Demo  
WITH EXECUTE AS 'CompanyDomain\SqlUser1'
....

 

 

 

参考文档:

EXECUTE AS Clause (Transact-SQL)

EXECUTE AS (Transact-SQL)

posted @ 2020-05-25 09:06  悦光阴  阅读(651)  评论(0编辑  收藏  举报