Get groups from Active Directory using C#
Asked Answered
E

2

7

I am having issues getting the groups from Active Directory via System.DirectoryServices

Originally I started my application on a computer that was registered on the domain, but as it was a live domain I did not want to do any writes to AD what so ever, so I set up a machine with Windows XP as the host operating system, and installed windows server 2003 on a VM.

I've added another Ethernet port in the machine and set up a switch, the 1 Ethernet port is dedicated to the VM and the other port is used for the host.

After configuring the IP addresses to get them communicating I transferred my application onto the host machine and fired it up, but I was getting an DirectoryServicesCOMException.

With the message that the user name and password was invalid :( just to check that it was not active directory I created a 3rd virtual machine and installed Windows XP, which i added to the domain with the credentials tested in the APP, works a treat.

So I thought it must be because the machine where the application is running is not part of the domain.

Heres the block of code that was causing the issue:

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;
     }
 }

The information in the login dialogue is being entered like so:

Domain: test.internal
Username: testaccount
Password: Password01

Hope someone can shed some light in this error.


Update:

After checking the Security Logs on the server i can see that my log in attempts was successful, but this is down to:

_IsValidLogin = Context.ValidateCredentials(Username, Password);

The line after where im checking the groups is causing the error, so the main issue is that the lines of code below are not working correctly from a machine thats not joined to the network:

var Results = UserPrincipal.FindByIdentity(Context, Username).GetGroups(Context);
Encrata answered 30/11, 2010 at 15:45 Comment(2)
Are you sure that the user credentials taken as input by the method arecorrect for the given domain you're attempting to authenticate the given user against? Does this user really exists? Have you tried the old-fashion approach using the DirectoryEntry and DirectorySearcher classes from the System.DirectoryServices namespace? Only suggestions, I don't know really about Principal objects.Dimissory
user exists as ive placed another VM XP machine on on the network with the same credentials, I can see the user in AD, and by running the command start \\server1 in cmd i get the credentials dialog and is able to auth via that, This works 100% on machines that are part of the network.Encrata
A
2

According to your code snippet, you're failing when you attempt to create the PrincipalContext, before calling ValidateCredentials. At that point the thread running your code is still working under either a local identity (if you're in a web process) or the identity you signed onto your machine with (for a windows process). Either of these won't exist on the test.internal domain.

You might want to try the overload of PrincipalContext that includes the username and password in the constructor. See http://msdn.microsoft.com/en-us/library/bb341016.aspx

Atom answered 30/11, 2010 at 16:8 Comment(2)
Ok I understand that, but if the PrincipleContext is failing how come in my Security logs on the server logs I can see a successful login with the user name coming from the client PC, I had a feeling it would be something to do with the local windows identity but I have tried doing: TEST/testaccount and testaccount@test and also [email protected] and all fail the same.. Also im sure I tried the overloads for Principle Context method, ill try again and update.Encrata
Wahhh, im sure it tested this :/, The line 'PrincipalContext(ContextType.Domain, Domain);' has been updated to hold the user name and password and seems to be working fine now.Encrata
C
2

I used to do quite a bit of user management via C# .NET. I just dug up some methods you can try.

The following two methods will get a DirectoryEntry object for a given SAM account name. It takes a DirectoryEntry that is the root of the OU you want to start searching for the account at.

The other will give you a list of distinguished names of the groups the user is a member of. You can then use those DN's to search AD and get a DirectoryEntry object.

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;
  }
}
Carvajal answered 30/11, 2010 at 16:13 Comment(2)
This is using Directory Entry which I do not want to use for the authentication process, DirectoryServices has a built namespace for handling called AccountManagementEncrata
yeah I was only talking about getting a list of what groups a user is a member of based off the title of your question.Carvajal

© 2022 - 2025 — McMap. All rights reserved.