9

在我掌握 Windows 中用户模拟的细微差别的过程中,我首先遇到了一个关于完全模拟远程数据库的问题(请参阅这个 SO question),但我终于想通了。我的下一个障碍是撤消/取消/恢复(选择您最喜欢的动词)模仿。

我尝试了几个对我来说似乎可信的不同模拟库:

结果与两个库相同。最佳实践要求对远程数据库连接使用 LOGON32_LOGON_NEW_CREDENTIALS 登录类型(请参阅 Windows API LogonUser 函数)。当我这样做时,这是我的示例代码产生的:

// SCENARIO A
BEGIN impersonation.
Local user = MyDomain\MyUser
DB reports: MyDomain\ImpersonatedUser
END impersonation.
Local user = MyDomain\MyUser
DB reports: MyDomain\ImpersonatedUser << NOT EXPECTED HERE!!

我发现的唯一解决方法是使用 LOGON32_LOGON_INTERACTIVE 登录类型,然后我得到这个:

// SCENARIO B
BEGIN impersonation.
Local user = MyDomain\ImpersonatedUser << EXPECTED, BUT NOT WANTED!
DB reports: MyDomain\ImpersonatedUser
END impersonation.
Local user = MyDomain\MyUser
DB reports: MyDomain\MyUser

WindowsImpersonationContext.Undo方法的简洁描述来看,它确实似乎应该在场景 A 中工作。

是否可以使用 LOGON32_LOGON_NEW_CREDENTIALS 登录类型进行还原?

4

3 回答 3

7

我深入研究了连接池的内部结构,结果发现 Windows 凭据根本不被视为连接池密钥的一部分。只有 SQL 登录会被考虑在内。

因此,如果在用户 A 下打开了一个可用连接,而您现在正在模拟用户 B,它仍然会使用它,并且 SQL 会将您视为用户 A。反之亦然。

为两个不同的用户稍微更改连接字符串的方法很好。如果您有一个“普通”用户,您可能会这样做,然后您需要模拟一些“提升”用户。当然,您不希望应用程序的每个用户都使用不同的字符串 - 否则您不妨完全禁用连接池。

调整连接字符串时,您可能会考虑将模拟用户名附加到Application NameorWorkstation ID字段。这将有利于为每个模拟用户设置一个单独的池。

于 2013-08-18T22:56:24.850 回答
6

感谢 Harry Johnston(在附加到问题的评论中)和 Phil Harding(在单独的通信中)的输入,我能够确定 SQL Server连接池是这里的罪魁祸首。由于池化是由连接字符串的唯一性决定的,因此通过稍微改变连接字符串(例如,颠倒参数的顺序,甚至只是在末尾添加一个空格),我观察到了我预期的行为。

===== TEST WITH SAME CONN STRING: True
BEGIN impersonation
Local user: MyDomain\msorens
DB reports: MyDomain\testuser
END impersonation
Local user: MyDomain\msorens
DB reports: MyDomain\testuser <<<<< still impersonating !!

===== TEST WITH SAME CONN STRING: False
BEGIN impersonation
Local user: MyDomain\msorens
DB reports: MyDomain\testuser
END impersonation
Local user: MyDomain\msorens
DB reports: MyDomain\msorens  <<<<< this is what I wanted to get
于 2013-08-17T21:22:26.083 回答
0

我发现登录类型 LOGON32_LOGON_NETWORK_CLEARTEXT 在模拟上下文中重复使用连接没有问题,并且在不改变连接字符串的情况下按预期工作。

根据这个线程,这种登录类型的“明文”部分似乎是服务器本地的。我只在数据库查询或一组查询期间使令牌保持活动状态,因此令牌的寿命很短。将这种登录类型用于长期令牌可能会也可能不会存在安全风险。

于 2019-01-31T17:51:04.953 回答