7

我在通过 Active Directory 获取组时遇到问题System.DirectoryServices

最初我在域中注册的计算机上启动我的应用程序,但由于它是一个实时域,我不想对 AD 进行任何写入,所以我设置了一台以 Windows XP 作为主机操作系统的机器,并在虚拟机上安装了 windows server 2003。

我在机器中添加了另一个以太网端口并设置了一个交换机,1 个以太网端口专用于 VM,另一个端口用于主机。

在配置 IP 地址以使它们进行通信后,我将我的应用程序转移到主机上并启动它,但我得到了一个DirectoryServicesCOMException.

提示用户名和密码无效 :( 只是为了检查它不是活动目录,我创建了第三个虚拟机并安装了 Windows XP,我使用在 APP 中测试的凭据将其添加到域中,这是一种享受.

所以我认为这一定是因为运行应用程序的机器不是域的一部分。

这是导致问题的代码块:

public CredentialValidation(String Domain, String Username, String Password, Boolean Secure)
{
     //Validate the Domain!
     try
     {
         PrincipalContext Context = new PrincipalContext(ContextType.Domain, Domain); //Throws Exception
         _IsValidDomain = true;

         //Test the user login
         _IsValidLogin = Context.ValidateCredentials(Username, Password);

         //Check the Group Admin is within this user
         //******HERE
         var Results = UserPrincipal.FindByIdentity(Context, Username).GetGroups(Context);

         foreach(Principal Result in Results)
         {
             if (Result.SamAccountName == "Domain Admins")
             {
                 _IsAdminGroup = true;
                 break;
             }
         }
         Results.Dispose();
         Context.Dispose();
     }
     catch (PrincipalServerDownException)
     {
         _IsValidDomain = false;
     }
 }

登录对话框中的信息是这样输入的:

Domain: test.internal
Username: testaccount
Password: Password01

希望有人能对这个错误有所了解。


更新:

检查服务器上的安全日志后,我可以看到我的登录尝试成功,但这归结为:

_IsValidLogin = Context.ValidateCredentials(Username, Password);

我检查组之后的行导致错误,所以主要问题是下面的代码行在未加入网络的机器上无法正常工作

var Results = UserPrincipal.FindByIdentity(Context, Username).GetGroups(Context);
4

2 回答 2

2

根据您的代码片段,在调用 ValidateCredentials 之前尝试创建 PrincipalContext 时失败。此时,运行您的代码的线程仍然在本地身份(如果您在 Web 进程中)或您在计算机上登录的身份(对于 Windows 进程)下工作。这些都不存在于 test.internal 域中。

您可能想尝试在构造函数中包含用户名和密码的 PrincipalContext 重载。请参阅http://msdn.microsoft.com/en-us/library/bb341016.aspx

于 2010-11-30T16:08:13.377 回答
2

我过去常常通过 C# .NET 进行大量用户管理。我只是挖了一些你可以尝试的方法。

以下两种方法将获取给定 SAM 帐户名称的 DirectoryEntry 对象。它需要一个 DirectoryEntry,它是您要开始搜索帐户的 OU 的根。

另一个将为您提供用户所属组的专有名称列表。然后,您可以使用这些 DN 搜索 AD 并获取 DirectoryEntry 对象。

public List<string> GetMemberOf(DirectoryEntry de)
{
  List<string> memberof = new List<string>();

  foreach (object oMember in de.Properties["memberOf"])
  {
    memberof.Add(oMember.ToString());
  }

  return memberof;
}

public DirectoryEntry GetObjectBySAM(string sam, DirectoryEntry root)
{
  using (DirectorySearcher searcher = new DirectorySearcher(root, string.Format("(sAMAccountName={0})", sam)))
  {
    SearchResult sr = searcher.FindOne();

    if (!(sr == null)) return sr.GetDirectoryEntry();
    else
      return null;
  }
}
于 2010-11-30T16:13:40.397 回答