模拟不适用于 DirectoryServices
Posted
技术标签:
【中文标题】模拟不适用于 DirectoryServices【英文标题】:Impersonate not working for DirectoryServices 【发布时间】:2012-03-08 15:51:31 【问题描述】:我正在尝试执行以下代码
using System.DirectoryServices;
public bool HasVirtualDirectory(string serverName, string virtualDirectoryName)
try
DirectoryEntry directoryEntry = new DirectoryEntry("IIS://" + serverName + "/W3SVC/1/Root");
return directoryEntry.Children.Find(virtualDirectoryName, directoryEntry.SchemaClassName.ToString()) != null;
catch (Exception)
return false;
由于我需要服务器上的管理员权限才能执行此代码,因此我使用this class 模拟了正确的用户:
using (Impersonator impersonator = new Impersonator("username", "domain", "password"))
server.HasAccess = HasVirtualDirectory(server.HostName, virtualDirectory);
但我仍然收到 COMException: Access is denied。另一方面,如果我不使用模拟,但我使用模拟中使用的相同凭据直接运行程序(通过在上下文菜单中使用“以不同用户身份运行”),它会按预期工作。
以管理员身份运行程序(运行程序的机器上的管理员,而不是服务器上的管理员)没有改变任何东西,异常仍然发生。
我还在 DuplicateToken 调用中尝试了 ImpersonationLevel.SecurityDelegation (=3) 而不是 ImpersonationLevel.SecurityImpersonation (=2),但这也没有改变任何东西(无论是作为普通用户还是执行程序的管理员用户)。
为了测试模拟代码,我尝试了以下代码,并且成功了。 (执行程序的用户无权创建目录,但被冒充的用户有)。
using (Impersonator impersonator = new Impersonator("username", "domain", "password"))
Directory.CreateDirectory(@"\\servername\c$\tmp");
我正在使用已激活 UAC 的 Windows 7 Professional。服务器是 Windows Server 2003 R2 SP2。
有人有什么想法吗?
【问题讨论】:
您应该参考从何处获得 Impersonator 类,因为它不是 .NET Framework 的一部分。我猜是这个,来自 Code Project 的codeproject.com/Articles/10090/…? 您是否尝试过使用接受用户名和密码而不是模拟的 DirectoryEntry 构造函数(String、String、String、AuthenticationTypes)? @JamieSee:如果您仔细查看我的问题,您会看到我提供了指向我使用的 Impersonator 类的链接。事实上,我从 CodeProject 类开始,但我还为 ImpersonationLevel 添加了一个枚举,就像在我链接的类中一样,所以我更喜欢链接那个,因为它更容易解释我对 ImpersonationLevel 的实验。 @JamieSee(2):我没有注意到其他构造函数,因为 HasVirtualDirectory 函数是由同事编写的,我没有检查它:(。我尝试使用DirectoryEntry directoryEntry = new DirectoryEntry("IIS://" + serverName + "/W3SVC/1/Root", @"domain\username", "password", AuthenticationTypes.Secure | AuthenticationTypes.Sealing);
和成功了!谢谢。提出您的建议作为答案,我会很高兴地接受它:)
很高兴这对您有所帮助。我已将其发布为答案。
【参考方案1】:
使用接受用户名和密码的DirectoryEntry Constructor (String, String, String, AuthenticationTypes) 而不是模拟。
DirectoryEntry directoryEntry = new DirectoryEntry("IIS://" + serverName + "/W3SVC/1/Root", @"domain\username", "password", AuthenticationTypes.Secure | AuthenticationTypes.Sealing);
【讨论】:
谢谢,成功了。但是,如果有人仍然可以告诉我为什么 Impersonate 不起作用,请继续 :)【参考方案2】:假设您使用的是 CodeProject 中的 Impersonator 类,请尝试更改登录类型,如 cmets 第 4 页的此帖子中所示:
嗨,乌维,
仅当您将 logonuser 函数中的登录类型更改为 LOGON32_LOGON_NEW_CREDENTIALS 时,它才适用于从 vista 进行远程访问。
const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
见LogonUser function
问候乌韦
【讨论】:
我忘了在我的问题中提及它,但我也阅读了该评论并尝试使用 LOGON32_LOGON_NEW_CREDENTIALS,它给出了同样的例外。我现在又试了一次,并尝试将它与 Duplicatetoken 中的 ImpersonationLevel.SecurityDelegation 结合起来和/或以管理员身份运行程序,但我总是遇到同样的异常。以上是关于模拟不适用于 DirectoryServices的主要内容,如果未能解决你的问题,请参考以下文章
android模拟位置不适用于locationservices.fusedlocationapi