LDAP issue

M

mbasil77

I'm trying to port a piece of Java LDAP conneciton code to DOTNET.
I've done LDAP in DOTNET before, but I keep getting a very strange
message. The Java code looks like:

public static boolean authenticate(String username, String password)
throws javax.naming.NamingException {
SearchControls sc;
NamingEnumeration ne;
Hashtable<String,String> h = new Hashtable<String,String>();

h.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
h.put(Context.PROVIDER_URL, "ldap://" + hostname + ":" + port);

if (usessl)
h.put(Context.SECURITY_PROTOCOL, "ssl");
if (servicedn != null) {
h.put(Context.SECURITY_AUTHENTICATION, "simple");
h.put(Context.SECURITY_PRINCIPAL, servicedn);
h.put(Context.SECURITY_CREDENTIALS, servicepassword);
}
DirContext ctx = new InitialDirContext(h);

String dn = "uid=" + username + ",ou=people," + base;
ctx.addToEnvironment(Context.SECURITY_AUTHENTICATION, "simple");
ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, dn);
ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);

try {
sc = new SearchControls();
sc.setSearchScope(SearchControls.OBJECT_SCOPE);
ne = ctx.search(dn, "(objectClass=*)", sc);
} catch (javax.naming.AuthenticationException e) {
return false;
}
return true;
}

The DOTNET code looks like:

static void Main(string [] args) {

String ldapAuthPath =
"LDAP://ldap.xxx.com/uid=xxx,ou=people,dc=xxx,dc=com";
String userName = "xxx";
String password = "pass";

DirectoryEntry rootEntry = null;
DirectorySearcher searcher = null;
SearchResult searchResult = null;

try {

rootEntry = new DirectoryEntry();

rootEntry.Path = ldapAuthPath;
rootEntry.Username = userName;
rootEntry.Password = password;
rootEntry.AuthenticationType = AuthenticationTypes.None;

searcher = new DirectorySearcher(rootEntry);
searcher.SearchScope = SearchScope.OneLevel;
searchResult = searcher.FindOne();

// if no exception the user was verified
Console.WriteLine("authenticated");
} catch (Exception e) {
// if exception user was not authenticated
Console.WriteLine(e.ToString());
}
}

I keep getting a message that the dn syntax is invalid. I've tried
various combinations of things. The Java code does not supply a
userName, but when I try to do this in DOTNET I get a invalid username
error.

Any ideas would be appreciated. It seems that the DOTNET API doesn't
offer the same degree of control.

mb
 
W

Willy Denoyette [MVP]

1. DirectoryEntry.UserName and Password are properties used to authenticate
the bind, you pecified an AuthenticationType.None that means you don't need
to specify the user credentials to bind.
2. You have (there are other options though) to specify the CN of the object
to bind to, like this:


using(DirectoryEntry user = new
DirectoryEntry("LDAP://ldap.xxx.com/CN=xxx,ou=people,DC=....")
{
try
{
PropertyCollection pcoll = user.Properties; // this will effectively
trigger the bind
Console.WriteLine(user.Properties["cn"].Value); // get a property
}
catch (DirectoryServicesCOMException ex)
{
Console.WriteLine(ex.Message);
}
}
Here you'll bind anonymously against the cn=xxxx, ou=people object in the
directory on ldap.xxx.com

Willy.


| I'm trying to port a piece of Java LDAP conneciton code to DOTNET.
| I've done LDAP in DOTNET before, but I keep getting a very strange
| message. The Java code looks like:
|
| public static boolean authenticate(String username, String password)
| throws javax.naming.NamingException {
| SearchControls sc;
| NamingEnumeration ne;
| Hashtable<String,String> h = new Hashtable<String,String>();
|
| h.put(Context.INITIAL_CONTEXT_FACTORY,
| "com.sun.jndi.ldap.LdapCtxFactory");
| h.put(Context.PROVIDER_URL, "ldap://" + hostname + ":" + port);
|
| if (usessl)
| h.put(Context.SECURITY_PROTOCOL, "ssl");
| if (servicedn != null) {
| h.put(Context.SECURITY_AUTHENTICATION, "simple");
| h.put(Context.SECURITY_PRINCIPAL, servicedn);
| h.put(Context.SECURITY_CREDENTIALS, servicepassword);
| }
| DirContext ctx = new InitialDirContext(h);
|
| String dn = "uid=" + username + ",ou=people," + base;
| ctx.addToEnvironment(Context.SECURITY_AUTHENTICATION, "simple");
| ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, dn);
| ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
|
| try {
| sc = new SearchControls();
| sc.setSearchScope(SearchControls.OBJECT_SCOPE);
| ne = ctx.search(dn, "(objectClass=*)", sc);
| } catch (javax.naming.AuthenticationException e) {
| return false;
| }
| return true;
| }
|
| The DOTNET code looks like:
|
| static void Main(string [] args) {
|
| String ldapAuthPath =
| "LDAP://ldap.xxx.com/uid=xxx,ou=people,dc=xxx,dc=com";
| String userName = "xxx";
| String password = "pass";
|
| DirectoryEntry rootEntry = null;
| DirectorySearcher searcher = null;
| SearchResult searchResult = null;
|
| try {
|
| rootEntry = new DirectoryEntry();
|
| rootEntry.Path = ldapAuthPath;
| rootEntry.Username = userName;
| rootEntry.Password = password;
| rootEntry.AuthenticationType = AuthenticationTypes.None;
|
| searcher = new DirectorySearcher(rootEntry);
| searcher.SearchScope = SearchScope.OneLevel;
| searchResult = searcher.FindOne();
|
| // if no exception the user was verified
| Console.WriteLine("authenticated");
| } catch (Exception e) {
| // if exception user was not authenticated
| Console.WriteLine(e.ToString());
| }
| }
|
| I keep getting a message that the dn syntax is invalid. I've tried
| various combinations of things. The Java code does not supply a
| userName, but when I try to do this in DOTNET I get a invalid username
| error.
|
| Any ideas would be appreciated. It seems that the DOTNET API doesn't
| offer the same degree of control.
|
| mb
|
 
M

mbasil77

I did a network trace and I think I see the issue. The Java code
switches over to SSLv3, whereas the DOTNET code does not. Anyone know
how to set that?

mb
1. DirectoryEntry.UserName and Password are properties used to authenticate
the bind, you pecified an AuthenticationType.None that means you don't need
to specify the user credentials to bind.
2. You have (there are other options though) to specify the CN of the object
to bind to, like this:


using(DirectoryEntry user = new
DirectoryEntry("LDAP://ldap.xxx.com/CN=xxx,ou=people,DC=....")
{
try
{
PropertyCollection pcoll = user.Properties; // this will effectively
trigger the bind
Console.WriteLine(user.Properties["cn"].Value); // get a property
}
catch (DirectoryServicesCOMException ex)
{
Console.WriteLine(ex.Message);
}
}
Here you'll bind anonymously against the cn=xxxx, ou=people object in the
directory on ldap.xxx.com

Willy.


| I'm trying to port a piece of Java LDAP conneciton code to DOTNET.
| I've done LDAP in DOTNET before, but I keep getting a very strange
| message. The Java code looks like:
|
| public static boolean authenticate(String username, String password)
| throws javax.naming.NamingException {
| SearchControls sc;
| NamingEnumeration ne;
| Hashtable<String,String> h = new Hashtable<String,String>();
|
| h.put(Context.INITIAL_CONTEXT_FACTORY,
| "com.sun.jndi.ldap.LdapCtxFactory");
| h.put(Context.PROVIDER_URL, "ldap://" + hostname + ":" + port);
|
| if (usessl)
| h.put(Context.SECURITY_PROTOCOL, "ssl");
| if (servicedn != null) {
| h.put(Context.SECURITY_AUTHENTICATION, "simple");
| h.put(Context.SECURITY_PRINCIPAL, servicedn);
| h.put(Context.SECURITY_CREDENTIALS, servicepassword);
| }
| DirContext ctx = new InitialDirContext(h);
|
| String dn = "uid=" + username + ",ou=people," + base;
| ctx.addToEnvironment(Context.SECURITY_AUTHENTICATION, "simple");
| ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, dn);
| ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
|
| try {
| sc = new SearchControls();
| sc.setSearchScope(SearchControls.OBJECT_SCOPE);
| ne = ctx.search(dn, "(objectClass=*)", sc);
| } catch (javax.naming.AuthenticationException e) {
| return false;
| }
| return true;
| }
|
| The DOTNET code looks like:
|
| static void Main(string [] args) {
|
| String ldapAuthPath =
| "LDAP://ldap.xxx.com/uid=xxx,ou=people,dc=xxx,dc=com";
| String userName = "xxx";
| String password = "pass";
|
| DirectoryEntry rootEntry = null;
| DirectorySearcher searcher = null;
| SearchResult searchResult = null;
|
| try {
|
| rootEntry = new DirectoryEntry();
|
| rootEntry.Path = ldapAuthPath;
| rootEntry.Username = userName;
| rootEntry.Password = password;
| rootEntry.AuthenticationType = AuthenticationTypes.None;
|
| searcher = new DirectorySearcher(rootEntry);
| searcher.SearchScope = SearchScope.OneLevel;
| searchResult = searcher.FindOne();
|
| // if no exception the user was verified
| Console.WriteLine("authenticated");
| } catch (Exception e) {
| // if exception user was not authenticated
| Console.WriteLine(e.ToString());
| }
| }
|
| I keep getting a message that the dn syntax is invalid. I've tried
| various combinations of things. The Java code does not supply a
| userName, but when I try to do this in DOTNET I get a invalid username
| error.
|
| Any ideas would be appreciated. It seems that the DOTNET API doesn't
| offer the same degree of control.
|
| mb
|
 
W

Willy Denoyette [MVP]

|I did a network trace and I think I see the issue. The Java code
| switches over to SSLv3, whereas the DOTNET code does not. Anyone know
| how to set that?
|
It will save you a lot of time if you would start reading the doc's on MSDN,
that said, ff you need to bind using SSL you'll have to set the
AuthenticationType.SecureSocketsLayer when creating an instance of
DirectoryEntry. Note that this requires a Certificate Server running on the
AD server, but I guess you aren't even connecting to a Windows LDAP server
(Active Directory server), so I can't guarantee this will even work in your
environment. Note that simple bind should work also, what happens when you
run the sample I posted?


Willy.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top