SQL Server"EXECUTE AS"出错

Vil*_*lx- 8 sql-server impersonation

我有以下设置:

有一个SQL Server数据库,其中有几个表设置了触发器(收集历史数据).这些触发器是CLR存储过程EXECUTE AS 'HistoryUser'.该HistoryUser用户是在数据库中的一个简单的用户无需登录.它具有足够的权限来读取所有表并写入历史表.

当我备份数据库然后将其还原到另一台机器(在这种情况下是虚拟机,但没关系)时,触发器不再起作用.事实上,不再模仿用户工作了.甚至像这样简单的陈述

exec ('select 3') as user='HistoryUser'
Run Code Online (Sandbox Code Playgroud)

产生错误:

无法作为数据库主体执行,因为主体"HistoryUser"不存在,此类主体不能被模拟,或者您没有权限.

在MSDN读到,如果数据库所有者是域用户,则会发生这种情况,但事实并非如此.即使我将其改为其他任何东西(他们推荐的解决方案),这个问题仍然存在.

如果我创建另一个没有登录的用户,我可以使用它进行模拟就好了.也就是说,这很好用:

create user TestUser without login
go
exec ('select 3') as user='TestUser'
Run Code Online (Sandbox Code Playgroud)

我不想重新创建所有这些触发器,所以我有什么方法可以完成现有的HistoryUser工作吗?

Eoi*_*ell 5

触发器执行的用户帐户是什么。

您需要为用户帐户 HistoryUser 授予该用户 IMPERSONATE 权限。

 GRANT IMPERSONATE ON USER:: YourUser TO HistoryUser
Run Code Online (Sandbox Code Playgroud)

更多细节在这里

http://msdn.microsoft.com/en-us/library/ms181362.aspx


Gre*_*son 5

检测孤立用户,然后通过链接到登录来解决.

DETECT:

USE <database_name>;
走;
sp_change_users_login @ Action ='Report';
走;

解决方案:
以下命令将<login_name>指定的服务器登录帐户与<database_user>指定的数据库用户重新链接:

USE <database_name>;
GO
sp_change_users_login @ Action ='update_one',@ UserNamePattern
='<database_user>',
@ LoginName ='<login_name>';

https://msdn.microsoft.com/en-us/library/ms175475.aspx