linux.net-coreldap

LDAP with dotnet core under Linux


I am developing an application based on .net core (2.2.103) which must connect to an LDAP server. On my development machine running Windows, I used the System.DirectoryServices namespace to do so. However, the application will have to run on Linux (Ubuntu) and I got a PlatformNotSupportedException, so I added a reference to <PackageReference Include="Novell.Directory.Ldap" Version="2.2.1" /> and used that.

Unfortunately, this throws another PlatformNotSupportedException (but because of Thread abort) when the Connection is disposed:

Unhandled Exception: System.PlatformNotSupportedException: Thread abort is not supported on this platform.
   at System.Threading.Thread.Abort()
   at Novell.Directory.Ldap.Connection.Dispose(Boolean disposing, String reason, Int32 semaphoreId, InterThreadException notifyUser)
   at Novell.Directory.Ldap.Connection.destroyClone(Boolean apiCall)
   at Novell.Directory.Ldap.LdapConnection.Finalize()

Is there any reliable LDAP implementation for dotnet core on Linux?


Solution

  • The package you tried to use was last updated in 2014. It's neither .NET Core nor .NET Standard compliant.

    You can try Novell.Directory.Ldap.NETStandard instead. Despite the name, this isn't a Novell library. There are other LDAP libraries in NuGet but this seems to be the most popular and is still actively developed.

    The exception suggests you forgot to dispose the connection too. Finalize is only called by the garbage collector.

    This answer shows how to use Novell.Directory.Ldap.NETStandard to authenticate a user :

    public bool ValidateUser(string domainName, string username, string password)
    {
       string userDn = $"{username}@{domainName}";
       try
       {
          using (var connection = new LdapConnection {SecureSocketLayer = false})
          {
             connection.Connect(domainName, LdapConnection.DEFAULT_PORT);
             connection.Bind(userDn, password);
             if (connection.Bound)
                return true;
          }
       }
       catch (LdapException ex)
       {
          // Log exception
       }
       return false;
    }
    

    The connection is created inside a using block which ensures it gets disposed as soon as execution leaves the block's scope