How to fetch attributes of LDAP entry?

  • Thread starter Thread starter Dennis Dobslaf
  • Start date Start date
D

Dennis Dobslaf

I try to do some authentication with LDAP. But it's a bit different to
the sample in msdn.
I wrote a class LdapAuthentication with a method

public bool IsAuthenticated(String domain, String username, String pwd)
{

String domainAndUsername = domain + @"\" + username;
DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, pwd,
AuthenticationTypes.Anonymous);

try
{
Object obj = entry.NativeObject;

DirectorySearcher search = new DirectorySearcher(entry);

search.Filter = "(cn=" + username + ")";
search.PropertiesToLoad.Add("cn");
SearchResult result = search.FindOne();

if ( null == result )
{
return false;
}
_path = result.Path;
result.GetDirectoryEntry();
_filterAttribute = (String)result.Properties["cn"][0];
}
catch(Exception ex)
{
throw new Exception("Error authenticating user: " + ex.Message );
}

return true;
}

The problem is, that the DirectorySearcher doesn't tell me if a user is
authenticated. It only tells me: an entry with (cn="+username+") has
been found.
The new _path shows me the way to my user (ldap://server/cn=user....).
The user has a attribute named userPassword (which is encrypted in
crypt-mode). So I have to compare the user input to the userPassword
stored in LDAP. My problem: I can't fetch out the userPassword! I need
it to get the salt.
I tried it with the following method (where _path is the whole path to
the user information):

public String GetPwd()
{
DirectoryEntry entry = new DirectoryEntry(_path);
DirectorySearcher search = new DirectorySearcher(entry);
search.PropertiesToLoad.Add("userPassword");

String ladpPwd = "";

try
{
SearchResult result = search.FindOne();
ladpPwd = result.Properties["userPassword"][0];

}
catch ( Exception ex )
{
throw new Exception("Could not find password: " + ex.Message );
}

return ldapPwd;
}

Maybe our LDAP is a little bit different or I don't understand the stuff!
 
Hi Dennis:

The new _path shows me the way to my user (ldap://server/cn=user....).
The user has a attribute named userPassword (which is encrypted in
crypt-mode). So I have to compare the user input to the userPassword
stored in LDAP. My problem: I can't fetch out the userPassword! I need
it to get the salt.

That feature is by design - if you think about it - you never actually
'see' passwords anywhere in Windows.

When you create the DirectoryEntry object you do so with a username
and password. This call doesn't attach to the AD with a bad username
and password. That's why the user is considered authenticated if
found.
 
That feature is by design - if you think about it - you never actually
'see' passwords anywhere in Windows.

When you create the DirectoryEntry object you do so with a username
and password. This call doesn't attach to the AD with a bad username
and password. That's why the user is considered authenticated if
found.

That's what I thought (at first). I'm not the LDAP guru so I searched in
msdn and found this:
http://msdn.microsoft.com/library/d...ve_directory_authentication_from_asp__net.asp

I used the LdapAuthentication class from the link above. The following
method throws an Exception:

public bool IsAuthenticated(String domain, String username, String pwd)
{
String domainAndUsername = domain + @"\" + username;
DirectoryEntry entry = new
DirectoryEntry(_path,domainAndUsername, pwd);

try
{
//Bind to the native AdsObject to force authentication.
Object obj = entry.NativeObject;

DirectorySearcher search = new DirectorySearcher(entry);

search.Filter = "(SAMAccountName=" + username + ")";
search.PropertiesToLoad.Add("cn");
SearchResult result = search.FindOne();

if(null == result)
{
return false;
}

//Update the new path to the user in the directory.
_path = result.Path;
_filterAttribute = (String)result.Properties["cn"][0];
}
catch (Exception ex)
{
throw new Exception("Error authenticating user. " + ex.Message);
}

return true;
}

@ Object obj = entry.NativeObject;

It throws an System.Runtime.InteropServices.COMException with the
message "Der Authentifizierungmethode ist unbekannt" same as "unknown
authentication mode" in english.
I tried to add AuthenticationTypes.Anonymous to the DirectoryEntry
object but then it seems that he doesn't search for any authentication,
but no other AuthType worked.
Also I could not use the Filter "SAMAccountName" (if I uses
'Anonymous'), I have to search for the 'cn'. I don't know if our LDAP is
different to others (it's openldap). If it is so, I have to search for
the solution on other places.
 
Also I could not use the Filter "SAMAccountName" (if I uses
'Anonymous'), I have to search for the 'cn'. I don't know if our LDAP is
different to others (it's openldap). If it is so, I have to search for
the solution on other places.

Oh, that could be. I'd look at the schema and properties available for
openLDAP - it probably does not have a SAMAccountName property as SAM
is Windows terminology. Perhaps you can find an article on
authenticating against openLDAP from another technology like Perl and
port the code.
 
Back
Top