Visual Studio .NET - LdapException: The LDAP server is unavailable in Web Application

Asked By kanthi kumar on 10-Jul-08 06:40 AM

hi,

I have a web app(ASP.net 2.0 VS 2005) where am trying to search for a user details in an LDAP.

am getting an exception"System.DirectoryServices.Protocols.LdapException: The LDAP server is unavailable" in my web app while trying to bind with a LDAP.

surprisingly the same piece of code works when i run my web application in debug mode. and works fine fine when i use this code in Windows application too.

below is the code that is used:

public int AuthenticateUser(string szNetID,string szPassword,out bool bAuthenticated){

int nReturn = 0;

string szFunctionName = "AuthenticateUser()";

bool bEntryFound = false;

string szLDAPSearchFilter = "", szDNForNetID = "";

LdapConnection obLdapConnection = null;

SearchRequest obSearchRequest = null;

SearchResponse obSearchResponse = null;

NetworkCredential obNetworkCredential = null;

LdapDirectoryIdentifier obLdapDirectoryIdentifier = null;

string szLDAPUserPrivDN = "XXXX";

string szLDAPUserPrivDNPassword = "XXXX";

string szLDAPServer = "XXXX";

string szLDAPServerPort = "XXXX";

bAuthenticated = false;

try

{

Response.Write("Binding");

obNetworkCredential = new NetworkCredential(szLDAPUserPrivDN, szLDAPUserPrivDNPassword);

obLdapDirectoryIdentifier = new LdapDirectoryIdentifier(szLDAPServer + ":" + szLDAPServerPort);

obLdapConnection = new LdapConnection(obLdapDirectoryIdentifier, obNetworkCredential, AuthType.Basic);

obLdapConnection.Bind();

}

catch (System.DirectoryServices.Protocols.LdapException obException)

{

nReturn = -3;

Response.Write(obException.Message);

}


 

finally

{

// Perform Cleanup

obNetworkCredential = null;

obLdapDirectoryIdentifier = null;

if (null != obLdapConnection)

{

obLdapConnection.Dispose();

obLdapConnection = null;

}

}

return nReturn;

}


is there any dependency of IIS while accessing  LDAP?


it may help u - Web Star replied to kanthi kumar on 10-Jul-08 06:44 AM

So, I took a look into this more and perhaps the part I am missing is whether or not you are sending your unique client certificate to the server.  Perhaps SDS does not support this (I think it does for AD at least).  Usually, all of this works for us under the covers.

Here is my take on doing this with SDS.P.  Of course, it might now work at all since I have no way of testing this unless you want to send me a certificate and there is public access to the server.

public class LdapSasl : IDisposable
{
    LdapConnection _connect;
   
    public LdapSasl(string server)
    {
        _connect = new LdapConnection(
            new LdapDirectoryIdentifier(server),
            null,
            AuthType.Basic
            );
           
        _connect.SessionOptions.ProtocolVersion = 3;
        _connect.SessionOptions.SaslMethod = "EXTERNAL";
        _connect.SessionOptions.SecureSocketLayer = true;

        //you need to open the store where
        //your certificate is located
        X509Store store = new X509Store(
            StoreName.My,
            StoreLocation.LocalMachine
            );
           
        X509Certificate2 cert = null;
       
        try
        {
            store.Open(OpenFlags.OpenExistingOnly);
            foreach (X509Certificate2 x509 in store.Certificates)
            {
                //I am just taking the first one,
                //but you can search the store using
                //Find method if you like.
                cert = x509;
                break;
            }
        }
        finally
        {
            if (store.StoreHandle != IntPtr.Zero)
                store.Close();
        }

        //add our specific client certificate
        if (cert != null)
        {
            _connect.ClientCertificates.Add(cert);
        }
    }
   
    public bool Authenticate()
    {
        try
        {
            _connect.Bind();
            return true;
        }
        catch (LdapException ex)
        {
            //49 means invalid creds
            if (ex.ErrorCode != 49)
                throw;

            return false;
        }
    }
   
    #region IDisposable Members

    public void Dispose()
    {
        if (_connect != null)
            _connect.Dispose();
    }

    #endregion
}


You can use it with something like this:

public class MyClass
{
    public static void Main()
    {
        using (LdapSasl sasl = new LdapSasl("localhost"))
        {
            bool truth = sasl.Authenticate();
           
            Console.WriteLine(
                "Bind {0} successful",
                truth ? "was" : "was not"
                );
               
            Console.ReadLine();
        }
    }
}


Well... that is about all I can unfortunately without having an environment myself.  Since this is something that I have not personally tried, it would be nice if you posted back when/if you figure out what finally works.

LDAP - Kalit Sikka replied to kanthi kumar on 10-Jul-08 06:52 AM

 

The first thing you should check the DNS, and make sure that both servers can resolve each other's name to the correct IP address.  The error message, The LDAP server is unavailable, is one I have encountered when name resolution is broken.

If name resolution is correct, you might try stopping and restarting the Exchange services on each side to see if that helps.


LDAP - kanthi kumar replied to Kalit Sikka on 10-Jul-08 07:11 AM

what i dont understand is, this code works when i use this function in a windows application.

the same works when i debug the web app.

Try these - Sakshi a replied to kanthi kumar on 10-Jul-08 07:12 AM

 you can try these links also,

http://forums.asp.net/p/949359/1730369.aspx

http://forums.iis.net/t/1137089.aspx


LDAP Client Certificate - kanthi kumar replied to Sakshi a on 10-Jul-08 08:29 AM

i think  the problem is with the client certificate.

what is x509 certificate?

the client certificate i currently instaled and using is of type ".cer".

the below code is failing to pick the certificate.


X509Store store = new X509Store(

StoreName.Root,

StoreLocation.LocalMachine

);

X509Certificate2 cert = null;

store.Open(OpenFlags.OpenExistingOnly);

textBox2.Text = "";

foreach (X509Certificate2 x509 in store.Certificates)

{

//I am just taking the first one,

//but you can search the store using

//Find method if you like.

textBox2.Text += x509.FriendlyName + "***";

if (x509.FriendlyName == "kanthi")

{

cert = x509;

break;

}

}


can someone please throw some light on this part?


ans LDAP Client Certificate - Sakshi a replied to kanthi kumar on 10-Jul-08 09:14 AM

what is X.509 ?

In cryptography, X.509 is an ITU-T standard for a public key infrastructure (PKI) and Privilege Management Infrastructure (PMI). X.509 specifies, amongst other things, standard formats for public key certificates, certificate revocation lists, attribute certificates, and a certification path validation algorithm.

You better contact the certificate provider or try it to open normally(ie not from the programm).