【发布时间】: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);和成功了!谢谢。提出您的建议作为答案,我会很高兴地接受它:) -
很高兴这对您有所帮助。我已将其发布为答案。
标签: c# directoryservices impersonation