在我掌握Windows用户模拟细节的旅程中,我首先遇到了一个让远程数据库冒充模拟的问题(看到这个问题 ),但我终于明白了这一点。 我的下一个障碍是取消/取消/还原(select你喜欢的动词)模仿。
我已经尝试了几个不同的模拟库,对我来说似乎是可信的:
结果与这两个库是相同的。 最佳做法指定远程数据库连接使用LOGON32_LOGON_NEW_CREDENTIALSlogintypes(请参阅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_INTERACTIVElogintypes,然后我得到这个:
// 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方法的简洁描述看来,它似乎应该在schemeA中起作用。
是否可以使用LOGON32_LOGON_NEW_CREDENTIALSlogintypes恢复?
感谢来自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
我深入到连接池的内部,结果证明Windows凭据根本不被认为是连接池的一部分。 只有SQL登录将被考虑在内。
因此,如果有一个在用户A下打开的可用连接,并且您现在正在模拟用户B,则它仍然会使用它,SQL会将您视为用户A.反之亦然。
为两个不同的用户稍微改变连接字符串的方法是好的。 如果你有一个“正常”的用户,你可能会这样做,然后你需要模仿一些“高”的用户。 当然,您不需要为应用程序的每个用户使用不同的字符串,否则您可能完全禁用连接池。
调整连接字符串时,可以考虑将模拟的用户名附加到“ Application Name
或“ Workstation ID
字段。 这将有利于为每个模拟用户设置单独的池。