Cannot get LDAP data using System.DirectoryServices.AccountManagement on IIS hosted app

Viewed 552

I am using System.DirectoryServices.AccountManagement Package to get users data from LDAP and it works fine on my local machine but on server, it gives error saying:

**An operations error occurred.

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)  

**

.NET Core version is 3.1, System.DirectoryServices.AccountManagement version is 6.0 and app is hosted on IIS on a VM (IIS version 8.0). The code I am using is:

List < ApplicationUser > users = new List < ApplicationUser > ();

using(var ctx = new PrincipalContext(ContextType.Domain, "mydomain")) {

  var userPrinciple = new UserPrincipal(ctx);
  using(var search = new PrincipalSearcher(userPrinciple)) {
    var results = search.FindAll().OrderBy(u => u.DisplayName);
    foreach(UserPrincipal domainUser in results) {
      var adUser = new ApplicationUser {
          Email = domainUser.EmailAddress,
          FirstName = domainUser.Name,
          PhoneNumber = domainUser.VoiceTelephoneNumber,
          UserName = domainUser.UserPrincipalName,
          EmployeeId = domainUser.EmployeeId
      };

      if (!String.IsNullOrWhiteSpace(adUser.Email)) {
        users.Add(adUser);
      }

    }
  }
}

So far I have tried application pool Identity change to Network Service but didnt work.

2 Answers

The stack trace shows that the exception is happening in DirectoryEntry.Bind, which is when it initially connects to AD. So something must be different between your computer and the server.

Is the domain accessible to the server? Any firewalls preventing access?

Is your computer joined to the domain, but the server is not? If this is the case, try using the full DNS name of the domain in the PrincipalContext constructor, if you aren't already (e.g. mydomain.com rather than just mydomain).

Are you using impersonation on the server? If so, that could be the issue. See here: https://stackoverflow.com/a/21547199/1202807

That is addressing ASP.NET (not Core), but it could be a similar issue.

After searching alot, I found an alternating solution:

List<ApplicationUser> users = new List<ApplicationUser>();
       
        using (var root = new DirectoryEntry(_ladapSettings.LDAPPathString, _ladapSettings.UserName, _ladapSettings.Password))
        {
            using (var searcher = new DirectorySearcher(root))
            {
                searcher.Filter = $"(&(objectCategory=person)(objectClass=user)(|(displayName=*{filter})(displayName={filter}*)))";
                var query = searcher.FindAll();

                foreach (SearchResult results in query)
                {
                    var de = results.GetDirectoryEntry();

                    if(de != null)
                    {

                        var adUser = new ApplicationUser
                        {
                            Email = de.Properties["mail"].Value?.ToString(),
                            UserName = de.Properties["mail"].Value?.ToString(),
                            FirstName = de.Properties["givenname"].Value?.ToString(),
                            LastName = de.Properties["sn"].Value?.ToString(),
                            PhoneNumber = de.Properties["telephoneNumber"].Value?.ToString(),
                            EmployeeId = de.Properties["employeeid"].Value?.ToString()
                        };

                        if (!String.IsNullOrWhiteSpace(adUser.Email))
                        {
                            users.Add(adUser);
                        }

                    }
                }
            }

This works fine on both local machine and on server.

Related