SQL Server 安全篇——数据层面安全性(3)——模拟(Impersonation)

2018-01-27 10:26:44来源:http://blog.csdn.net/dba_huangzj/article/details/79092896作者:黄钊吉的博客人点击

分享

接上文: SQL Server 安全篇——数据层面安全性(2)——所有权链接( Ownership Chaining)


模拟是指在不同安全主体的上下文下执行T-SQL语句或代码模块的做法。用来最小化权限授予和授予权限的用户数,但是不影响执行时提升到所需的权限。实际上,在会话或模块的执行期间,模拟起到了用户或登录名切换的过程。也可以不严谨地认为,发起模拟的用户A借用B的身份执行了B有权限但A没权限做的事。


在SQL Server中,可以使用EXECUTE AS子句来实现模拟功能。EXECUTE AS可以位于存储过、函数、DML触发器的头部。也可以用于会话过程切换安全上下文。下表是EXECUTE AS可用场景:



用处
上下文规范(Context Specification)
Session(会话)

LOGING
USER

存储过程、函数、DML触发器

CALLER
SELF
OWNER
USER

库级别DDL触发器

CALLER
SELF
USER

服务器级别DDL触发器

CALLER
SELF
LOGIN

Queues(队列)

CALLER
SELF
USER


上下文规范(Context Specification)说明


CALLER:意味着代码运行在原始上下文,是除队列之外的默认行为。
SELF:代码在创建或最后更改模块的主体的上下文下执行。
OWNER:代码运行在安全主体的拥有者上下文。
USER:以数据库特定用户运行代码。
LOGIN:以特定登录名来运行代码。

下面来演示一下,首先创建一个登录名George:


USE master
GO
CREATE LOGIN George
WITH PASSWORD='强密码',
DEFAULT_DATABASE=master, CHECK_EXPIRATION=OFF, CHECK_POLICY=ON ;
GO 然后在演示库创建一个用户,关联这个登录名:

USE AdventureWorks2016
GO
CREATE USER George FOR LOGIN George

然后调用不带参数的SUSER_SNAME()函数返回当前安全上下文的登录名(注意这里不能是“组”或者“绝色”,必须是单一账号):


USE AdventureWorks2016
GO
--以当前上下文运行
SELECT SUSER_SNAME() ;
--转换当前上下文为George用户
EXECUTE AS USER = 'George' ;
--再次查询
SELECT SUSER_NAME() ;

结果如图:



第一个查询运行在我自己的登录名的安全上下文中,当执行完EXECUTE AS语句之后,上下文切换成George,但是注意除非你关掉这个界面,不然需要使用REVERT命令来恢复上下文,否则将一直以George的上下文来运行。


准确来说,在下面情况发生之前,切换后的上下文一直有效:


运行另一个Execute AS语句
运行REVERT语句
删除会话(比如SSMS关闭查询窗口)
存储过程或触发器中的命令执行了退出操作。

注意:对于即席查询(ad hoc SQL)的EXECUTE AS子句,必须在安全上下文中具有模拟权限,否则使用EXECUTE AS也会报错。另外,非包含数据库或SQL DB(Azure上)之外的模拟,其执行返回限制于服务器级别。


最佳实践:

首先当然还是要维持最低所需权限。比如只需要DB级别的就不要给Server级别的权限。当需要在一个过程中切换多次登录时(不建议),要保持原始登录的识别,以免后续忘记切回去,这个原始登录可以通过ORIGINAL_LOGIN函数来获取。


最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台