模拟不适用于DirectoryServices

时间:2012-03-08 15:51:32

标签: c# directoryservices impersonation

我正在尝试执行以下代码

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:访问被拒绝。另一方面,如果我不使用模拟,但我使用我在模拟中使用的相同凭据直接运行程序(通过在上下文菜单中使用“以不同用户身份运行”),它按预期工作。

以管理员身份运行程序(运行程序的计算机上的管理员,而不是服务器上的管理员)没有更改任何内容,但异常仍然存在。

我还在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。

有没有人有任何想法?

2 个答案:

答案 0 :(得分:2)

使用带有用户名和密码的DirectoryEntry Constructor (String, String, String, AuthenticationTypes)代替模拟。

DirectoryEntry directoryEntry = new DirectoryEntry("IIS://" + serverName + "/W3SVC/1/Root", @"domain\username", "password", AuthenticationTypes.Secure | AuthenticationTypes.Sealing);

答案 1 :(得分:0)

假设您正在使用CodeProject中的Impersonator类,请尝试从注释的第4页更改此帖子中指示的登录类型:

  

Hi Uwe,

     

当您将logonuser函数中的logontype更改为LOGON32_LOGON_NEW_CREDENTIALS时,它仅适用于从vista远程访问。

     

const int LOGON32_LOGON_NEW_CREDENTIALS = 9;

     

请参阅LogonUser function

     

问候Uwe