简体   繁体   中英

OpenLdap C# bind with escaped characters in Distinguished Name

I have some working LDAP code in which we rebind to the found user in order to validate the user, using his distinguished name. Effectively this is what is happening:

            string userDn = @"cn=Feat Studentl+umanroleid=302432,ou=Faculty of Engineering & Physical Sciences Administration,ou=Faculty of Engineering & Physical Sciences,ou=People,o=University of TestSite,c=GB";
            string fullPath = @"LDAP://surinam.testsite.ac.uk:636/" + userDn;

            DirectoryEntry authUser = new DirectoryEntry(fullPath, userDn, "mypassword", AuthenticationTypes.None);

            authUser.RefreshCache();

However this causes error unknown error 80005000 at DirectoryEntry.Bind()

I suspected the problem might be that the DN has a '+' and a '=' in the CN attribute. Therefore after finding that the way to escape this should be with a \\ and the hex value of the character I tried this:

            string userDn = @"cn=Feat Studentl\2Bumanroleid\3D302432,ou=Faculty of Engineering & Physical Sciences Administration,ou=Faculty of Engineering & Physical Sciences,ou=People,o=University of TestSite,c=GB";

However I get the error:

Login failure: unknown user name or bad password

I assume this is because that now it is happy with the request but it is failing to match the users DN, for some reason.

Is there anyway around this?

In my experience developing LDAP services, whenever you get a login failure due to invalid credentials, that does tend to be the issue with the bind attempt. You're getting that error because DirectoryEntry does not parse the escaped characters in the DN... however, you shouldn't have to do that in the first place.

In your code - setting the AuthenticationTypes to "None" forces the entry to make a Simple bind based on the DN you're providing. Since your including the server name as part of the path, I would try using the ServerBind auth type instead, like this :

string LdapPath = ("LDAP://" + ldapUrl + "/" + Domain);

//Build the user and issue the Refresh bind
var dirEntry = new DirectoryEntry
                   {
                       Path = LdapPath,
                       Username = _usernameToVerify,
                       Password = _passwordToVerify,
                       AuthenticationType = AuthenticationTypes.ServerBind
                   };

//This will load any available properties for the user
dirEntry.RefreshCache();

Also, it looks like you're making this call to the secure LDAP port (636), so make sure you also include AuthenticationTypes.SecureSocketsLayer along with the ServerBind mechansim :

AuthenticationType = AuthenticationTypes.ServerBind | AuthenticationTypes.SecureSocketsLayer

Hope this helps!

I had to resort to digging through an old DLL project that was customised for one customer.

I managed to get it to work. It appears you have to refer to these low level Directory Services routines if you have a DN with escape characters. (Note in real life the DN is obtained by an initial felxible user search by setting up a DirectorySearcher and doing FindOne first)

 string userDn = @"cn=Feat Studentl+umanroleid=302432,ou=Faculty of Engineering & Physical Sciences Administration,ou=Faculty of Engineering & Physical Sciences,ou=People,o=University of TestSite,c=GB";
 string basicUrl = @"surinam.testsite.ac.uk:636";



  var ldapConnection = new LdapConnection(basicUrl);
  ldapConnection.AuthType = AuthType.Basic;
  LdapSessionOptions options = ldapConnection.SessionOptions;
  options.ProtocolVersion = 3;
  options.SecureSocketLayer = true;

  NetworkCredential credential = new NetworkCredential(userDn, password);                             
  ldapConnection.Credential = credential;

  try
  {
      ldapConnection.Bind();
      Console.WriteLine("bind succeeded ");
  }
  catch (LdapException e)
  {
      if (e.ErrorCode == 49)
      {
           Console.WriteLine("bind failed ");
      }
      else
      {
          Console.WriteLine("unexpected result " + e.ErrorCode);
      }
  }
  catch (DirectoryOperationException e)
  {
      Console.WriteLine("unexpected error " + e.Message);
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM