Active Directory Get List of Users using PrincipalSearcher throws error

1.8k Views Asked by At

I have two functionality which I need to achieve in asp.net web application.

  1. Authenticate using Active Directory
  2. Get list of Active Directory users.

Both above work fine on client environment when I set IIS application pool to Network Service. When I change back to IIS user then only authentication works but to get the list of users stops working. I am not sure why it is happening.

Here is my code:

  1. Authentication:

    public bool AuthenticateADUser(string domain, string password, string username)
    {
        bool isValid = false;
    
        using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, domain))
        {
            isValid = pc.ValidateCredentials(username, password);
        }
    
        return isValid;
    }
    
  2. Get the list of Active Directory users:

    using (var context = new PrincipalContext(ContextType.Domain, domain))
    {
        if (groupName != string.Empty)
        {   
            // get list of users for a group
            GroupPrincipal group = GroupPrincipal.FindByIdentity(context, groupName);
    
            foreach (Principal principal in group.Members)
            {                            
                AdUsers.Add(principal);                            
            }                        
        }
        else   // get all users regardless of group
        {
            using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
            {
                foreach (Principal principal in searcher.FindAll())
                {
                    if (principal.UserPrincipalName != null)
                        AdUsers.Add(principal);
                }                            
            }  //end PrincipalSearcher using 
        }  //end else
    }  //end PrincipalContext using    
    

Updated: I can't say which line of code because I deployed the application to client server, so can't debug it. But here is the error:

Exception information:

Exception type: DirectoryServicesCOMException 
Exception message: Logon failure: unknown user name or bad password.

at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
at System.DirectoryServices.DirectoryEntry.Bind()
at System.DirectoryServices.DirectoryEntry.get_AdsObject()
at System.DirectoryServices.PropertyValueCollection.PopulateList()
at System.DirectoryServices.PropertyValueCollection..ctor(DirectoryEntry entry, String propertyName)
at System.DirectoryServices.PropertyCollection.get_Item(String propertyName)
at System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInitNoContainer()
at System.DirectoryServices.AccountManagement.PrincipalContext.DoDomainInit()
at System.DirectoryServices.AccountManagement.PrincipalContext.Initialize()
at System.DirectoryServices.AccountManagement.PrincipalContext.get_QueryCtx()
at System.DirectoryServices.AccountManagement.PrincipalSearcher.SetDefaultPageSizeForContext()
at System.DirectoryServices.AccountManagement.PrincipalSearcher..ctor(Principal queryFilter)
at WarshawGroup.OneVoice.User.bus_cUser.GetADUsers(String domain, String groupName)
at WarshawGroup.OneVoice.UI.Data.Users.Modify.Page_Load(Object sender, EventArgs e)
at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)
at System.Web.UI.Control.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

Updated:

It throws an exception at

 var searcher = new PrincipalSearcher(new UserPrincipal(context)); 

Context is PrincipalContext type...

 var context = new PrincipalContext(ContextType.Domain, domain);

PrincipalContext has property called "ConnectedServer". The value for ConnectedServer is null, so it throws the exception.

If I pass user name and password along with domain in PrincipalContext, everything works.Example...

 var context = new PrincipalContext(ContextType.Domain, domain,"username","pwd");

It seems like I need to impersonate the user who has permission to access a particular domain.

Is there any other way I can achieve this?

Thanks,

0

There are 0 best solutions below