none
LDAPS Authentication in asp.net application RRS feed

  • Question

  • Hi,

    I can't connect my c# application to a LDAPS server.

    Earlier, i was able to connect to LDAP server by using the following code:

    string srvr = ConfigurationManager.AppSettings["LDAP_SERVER"]; //where "LDAP_SERVER" is server url ex: "LDAP//domain_name".

    DirectoryEntry entry = new DirectoryEntry(srvr, usr, pwd); // usr-domain user id , pwd-domain password

    object nativeObject = entry.NativeObject;

    But, recently we had to update our servers to LDAPS. The above code does not work with LDAPS server (server url looks like "LDAPS://ldap.domain_name").

    Can anyone suggest on how to authenticate users over LDAPS server?

    Thanks in advance.

    Regards,

    Praveen.

    Monday, March 16, 2020 11:33 AM

All replies

  • Are you impacted by the recent change in Windows where LDAP signing is now required? You'll need to update your code that calls into LDAP to ensure it is signed and that your back end server supports it. At a minimum you'll need to adjust the code that connects to LDAP to use the appropriate connection settings. You didn't post that code so we'd be guessing but here's the relevant link if you're using PrincipalContext. Specifically ContextOptions has the settings that are needed.

    If that doesn't work then post the exact code you're using to connect, confirm you have properly updated your LDAP servers and provide the exact exception information including stack trace and type.


    Michael Taylor http://www.michaeltaylorp3.net

    Monday, March 16, 2020 1:46 PM
    Moderator
  • Yes. We are asked to use "LDAPS" protocol instead of "LDAP".

    The code used for "LDAP" protocol was:

    public int IsLDAPAuthenticated(string usr, string pwd)
        {
            string srvr = ConfigurationManager.AppSettings["LDAP_SERVER"]; //the value of "LDAP_SERVER" key was "LDAP://domain_name/")

            int authenticated = 0;

            try
            {
                DirectoryEntry entry = new DirectoryEntry(srvr, usr, pwd);
                object nativeObject = entry.NativeObject;
                authenticated = 0;
            }
            catch (Exception)
            {
                //not authenticated due to some other exception [this is optional]
                authenticated = 1;  //bad user, password, expired etc
            }

            return authenticated;
        }

    Now, our new "LDAP_SERVER" url looks like "LDAPS://domain_name/"

    Can you tell what are the changes required here to authenticate users over this new url?

    I have tried using "PrincipalContext" and this uses only domain name for authentication. And it works fine when i pass only domain name. But how can i use the complete URL( "LDAPS://domain_name/" ) for authentication as earlier?

    Regards,

    Praveen.

    Tuesday, March 17, 2020 7:45 AM
  • hello friend

    IF change to ssl then use port 636 try the bellow code

    Port 636 is for SSL. Try directly with LdapConnection to make sure you can access that server via SSL (SecureSocketLayer = true):
    using (var ldapConnection = new LdapConnection("my.ad.server:636")) {
                        var networkCredential = new NetworkCredential(username, password, "my.ad.server");
    ldapConnection.SessionOptions.SecureSocketLayer = true;
                        ldapConnection.AuthType = AuthType.Negotiate;
                        ldapConnection.Bind(networkCredential);
                    }
    

    Tuesday, March 17, 2020 1:50 PM
  • I think you can just add the extra parameter of type AuthenticationTypes to the creation of the DirectoryEntry. Add the option to use SSL which should be equivalent to using the same setting on PrincipalContext. I cannot test this myself but it seems correct based upon the docs.

    var entry = new DirectoryEntry(domain, userName, password, AuthenticationTypes.SecureSocketsLayer);

    But note that I don't believe this is the correct way to authenticate. You should be creating the context using PrincipalContext. Then use its ValidateCredentials to validate the credentials of the user. That lines up with what your function is called as well. Something like this (again not tested because I don't have access to an LDAP server).

    static bool IsLDAPAuthenticated ( string domain, string userName, string password )
    {
        try
        {
            //Note that if this function will be used for validating several people then consider 
            //caching the context to save time
            var options = ContextOptions.SecureSocketLayer | ContextOptions.Negotiate;
            using (var context = new PrincipalContext(ContextType.Domain, domain, null, options))
            {
                return context.ValidateCredentials(userName, password);
            };
        } catch (Exception e)
        { /* Ignore */ };
                
        return false;
    }


    Michael Taylor http://www.michaeltaylorp3.net

    Tuesday, March 17, 2020 2:07 PM
    Moderator
  • Just adding an extra parameter of type AuthenticationTypes to the creation of the DirectoryEntry works with LDAP protocol but gives an unknown error with LDAPS.

    I have also tried the above solution using PrincipalContext and it works with both LDAP and LDAPS servers on providing domain_name. But the requirement here is to use the complete domain path(like LDAPS://my.ad.server/) where as this method uses only the domain_name ("my.ad.server").

    Is there a method/library which accepts this new complete path(LDAPS://my.ad.server/) for authentication similar to DirectEntry()?

    Thanks.

    Tuesday, March 17, 2020 6:21 PM
  • I'm not sure it really matters for PC. LDAP uses one port and LDAPS uses another. The scheme is needed when using DirectoryEntry so it can figure out what it is dealing with. While I haven't searched the PC code I believe it will handle this for you already. Here's a discussion about the differences. Ultimately provided you're using SSL and the correct port (different between LDAP and LDAPS) then it should connect to the correct URL. However if you really need to use the lower level LdapConnection you could based upon the link given earlier.


    Michael Taylor http://www.michaeltaylorp3.net

    Tuesday, March 17, 2020 6:49 PM
    Moderator