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);
RobertPitt
  • 56,863
  • 21
  • 114
  • 161
  • 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. – Will Marcouiller Nov 30 '10 at 15:52
  • 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. – RobertPitt Nov 30 '10 at 16:00

2 Answers2

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

Dave Markle
  • 95,573
  • 20
  • 147
  • 170
John Christensen
  • 5,020
  • 1
  • 28
  • 26
  • 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 `testaccount@test.internal` and all fail the same.. Also im sure I tried the overloads for Principle Context method, ill try again and update. – RobertPitt Dec 01 '10 at 09:19
  • 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. – RobertPitt Dec 01 '10 at 09:48
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;
  }
}
Frank Hale
  • 1,886
  • 1
  • 17
  • 31
  • This is using Directory Entry which I do not want to use for the authentication process, `DirectoryServices` has a built namespace for handling called `AccountManagement` – RobertPitt Dec 01 '10 at 09:22
  • 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. – Frank Hale Dec 02 '10 at 15:51