C# 使用C从Active Directory获取组#

C# 使用C从Active Directory获取组#,c#,active-directory,active-directory-group,C#,Active Directory,Active Directory Group,通过System.DirectoryServices从Active Directory获取组时遇到问题 最初,我在域上注册的计算机上启动了我的应用程序,但由于它是一个活动域,我不想对AD执行任何写入操作,因此我设置了一台以Windows XP作为主机操作系统的计算机,并在VM上安装了Windows server 2003 我在机器中添加了另一个以太网端口并设置了一个交换机,1个以太网端口专用于VM,另一个端口用于主机 在配置IP地址以使它们通信后,我将应用程序转移到主机上并启动了它,但我得到了一

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

最初,我在域上注册的计算机上启动了我的应用程序,但由于它是一个活动域,我不想对AD执行任何写入操作,因此我设置了一台以Windows XP作为主机操作系统的计算机,并在VM上安装了Windows server 2003

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

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

显示用户名和密码无效的消息:(只是为了检查它是否为active directory,我创建了第三个虚拟机并安装了Windows XP,我使用应用程序中测试的凭据将其添加到域中,效果良好

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

以下是导致问题的代码块:

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);
im检查组后的那一行导致了错误,因此主要问题是以下代码行在未连接到网络的机器上无法正常工作:


根据您的代码片段,在调用ValidateCredentials之前尝试创建PrincipalContext时失败。此时,运行代码的线程仍在使用本地标识(如果您在web进程中)或登录到计算机上的标识(对于windows进程)工作。test.internal域中将不存在这两个域中的任何一个


您可能想尝试PrincipalContext的重载,该重载在构造函数中包含用户名和密码。请参见

我曾经通过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;
  }
}
public List GetMemberOf(DirectoryEntry de)
{
List memberof=新列表();
foreach(de.Properties[“memberOf”]中的对象oMember)
{
memberof.Add(oMember.ToString());
}
返回成员;
}
public DirectoryEntry GetObjectBySAM(字符串sam,DirectoryEntry根目录)
{
使用(DirectorySearcher searcher=newdirectorysearcher(root,string.Format(((sAMAccountName={0})”,sam)))
{
SearchResult sr=searcher.FindOne();
如果(!(sr==null))返回sr.GetDirectoryEntry();
其他的
返回null;
}
}

您是否确定该方法输入的用户凭据对于您试图对给定用户进行身份验证的给定域是正确的?该用户是否确实存在?您是否使用
System.DirectorySe中的
DirectoryEntry
DirectorySearcher
类尝试过旧方法服务
namespace?仅提供建议,我不太了解主体对象。用户存在,因为我在网络上放置了另一台具有相同凭据的VM XP计算机,我可以在AD中看到该用户,通过在cmd中运行命令
start\\server1
,我可以获得凭据对话框并能够通过该对话框进行身份验证,这在ma上100%有效作为网络一部分的中文。好的,我理解,但是如果PrincipleContext失败了,为什么在我的服务器日志上的安全日志中我可以看到一个成功的登录,用户名来自客户端PC,我有一种感觉,这可能与本地windows标识有关,但我尝试过这样做:
TEST/testaccount
testaccount@test
testaccount@test.internal
所有测试都失败了。另外,我确定我尝试了Principal上下文方法的重载,我将重试并更新。哇,我确定它测试了以下内容:/,行“PrincipalContext”(ContextType.Domain,Domain);'已更新为保存用户名和密码,现在似乎工作正常。这是使用我不想用于身份验证过程的目录项,
DirectoryServices
有一个用于处理的内置命名空间,名为
AccountManagement
是的,我只是说获取用户所属组的列表根据你问题的标题,一位委员会成员。
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;
  }
}