I'm also trying to conncect to LDAP with SSL. I need it to authenticate users. Somehow I got it working, but there are several things which do not work as I think they should: I cannot use LDAPS:// but only LDAP://, because it results in an unknown error.
Anyway the connection is established via port 636 and seems to be encrypted when I look at it in wireshark.
In addition the variable AuthenticationType seems to have no effect. The data which is transmitted is encrypted anyway.
The final problem is that there is know way to check the certificate. I could only do it seperatly.
Does anyone know how to fix any of my problems? Anyway my code works somehow and you can use it if you want to.
Here it is:
private String LDAP_ServerAddress = "ldap.xyz.com";
private String LDAP_BaseDN = "ou=sub,o=xyz.com";
/// <summary>
/// This method authenticates a user with his password via LDAP
/// </summary>
/// <param name="user">User to authenticate</param>
/// <param name="password">Users password</param>
/// <returns>Whether user + password is correct</returns>
public Boolean authenticateUser(String user, String password)
{
//Create a directory entry with port 636 (LDAP SSL)
DirectoryEntry objDirEntry = new DirectoryEntry("LDAP://" + this.LDAP_ServerAddress + ":636/" + this.LDAP_BaseDN);
//Add the username, it has to be the complete path
objDirEntry.Username = "uid="+user+",ou=sub,o=xyz.com";
//Add the users password
objDirEntry.Password = password;
//Authentication Type seems to have no effect
objDirEntry.AuthenticationType = AuthenticationTypes.None;
try
{
//method to test the connection/username/password
object nativeObject = objDirEntry.NativeObject;
objDirEntry.Close();
}
//catch exceptions(timeout, bad username or password)
catch (COMException exception)
{
//errorcode -2147023570 bad username or password
if (exception.ErrorCode == -2147023570) return false;
// errorcode -2147016646 -> timeout
else throw new Exception("Exception in LDAPConenctor.cs Method: void authenticateUser(): " + exception.ToString(), exception);
}
return true;
}
I have the same problem. And I am using very similar code like yours for the SSL connection. However, it refuses to work for some certificate problem. Apparently the security certificate used by the LDAP server is not trusted by the client. I have imported
every certificate into the trusted root store on the client, but the ASP.net application seems not to check against them. Do you know anything about it? How is your testing environment set up? Any suggestion?
I am trying to authenticate users through LDAP SSL.
As far as i have understood,The different ways to connect to an AD and search is by using a directory entry object or by using a search request object.
For LDAP SSL is it just enough to turn the AuthenticateType to SSL?
What else should we do to enable SSL?Do we need to import any client certificates?
could you please tell me any pre-requisites the client has to do to their AD for LDAPS?
I have not really understood the servercall back?Is this used to check if the server has a valid certificate?
From the product we just need to communicate to the AD securely,so what are the best ways to do it?
Your code seems to be exactly what I'm trying to do, but when I implement it on my system, it's not working. It fails on the con.Bind() line saying "The LDAP server is unavailable."
The way that I implemented it was I created a form with Server, Port, Username & Password. When a user clicks the button I call the CreateConnection method and then the LDAPSAuthenticate() method.
It appears to create the connection object properly. The con object is not null at least. I did notice that the con.SessionOptions.HostName & .DomainName are both null. I'm not sure if they get populated after the Bind method.
Everything works great when I use the DirectoryEntry class except I don't know how to ignore the Server Cert Verification, which I believe is what your code is supposed to fix. Any ideas? Thanks a ton!
This thread is a bit old, but I'm hoping someone might still respond as I am also running into this issue.
I tried the LdapConnection method specified above after the DirectorySearcher method failed to connect with SSL. I built a windows forms application that was able to successfully connect, but when I move the code to ASP.NET it fails. I wonder if there
is a permission I need to grant to Network Services?
julplemet
0 Points
2 Posts
Connection to a secured LDAP (SSL)
Apr 14, 2010 11:56 AM|LINK
Hi,
I can't connect my c# website to a LDAP server over SSL. When using ldap browsers, I can do it (they ask me to manually validate the certificate).
When I do it in c#, I receive differents exceptions depending on my tests (unknown error, not operationnal server...)
Note: I have no problem when I try to connect to a not SSL connection.
If anyone could help me, this server is bindable for tests (ldapv3):
server: ldapclient.com
port: 389
authentication: anonymous
or with SSL
server: ldapclient.com
port: 636
authentication: anonymous
And there is one of the various codes I try:
public byte[] GetRecipientCertificateFromLDAPStore()
{
SearchResultCollection col;
DirectorySearcher searcher = new DirectorySearcher();
string[] resultsFields = new string[] { "cn", "mail", "usercertificate;binary" };
//Pass the IPAddress and the Port of the LDAP Server.
string[] textArray1 = new string[] { "LDAP://", "ldapclient.com", ":", "636", "" };
searcher.SearchRoot = new DirectoryEntry(string.Concat(textArray1), null, null, AuthenticationTypes.SecureSocketsLayer);
searcher.SearchScope = System.DirectoryServices.SearchScope.Subtree;
searcher.PropertiesToLoad.AddRange(resultsFields);
searcher.Filter = string.Format("(&(cn={0})(mail={1}))", "* *", "* *");
col = searcher.FindAll();
X509Certificate2 certificate1 = new X509Certificate2();
foreach (SearchResult result1 in col)
{
IEnumerator enumerator2;
try
{
enumerator2 = result1.GetDirectoryEntry().Properties["usercertificate;binary"].GetEnumerator();
while (enumerator2.MoveNext())
{
object obj1 = RuntimeHelpers.GetObjectValue(enumerator2.Current);
certificate1.Import((byte[])obj1);
//Can access different Properties for example:
//certificate1.Subject;
//certificate1.SerialNumber;
//certificate1.Version;
//certificate1.NotBefore;
//certificate1.NotAfter;
//certificate1.Issuer;
return certificate1.Export(X509ContentType.Cert);
}
}
catch { }
}
return null;
}
Thanks for any help!
Julien
julplemet
0 Points
2 Posts
Re: Connection to a secured LDAP (SSL)
Apr 14, 2010 01:55 PM|LINK
Does anybody succeed to connect to ldapclient.com over SSL in c#?
Please help me.
Julien
sita_krish
Member
4 Points
2 Posts
Re: Connection to a secured LDAP (SSL)
May 17, 2010 03:02 PM|LINK
Hi Julien,
I am also looking for same task to connect to an LDAP server using SSL
Have you succeeded in finding this out?
Krishna
MrY
Member
2 Points
1 Post
Re: Connection to a secured LDAP (SSL)
Jun 01, 2010 10:17 AM|LINK
Hi,
I'm also trying to conncect to LDAP with SSL. I need it to authenticate users. Somehow I got it working, but there are several things which do not work as I think they should: I cannot use LDAPS:// but only LDAP://, because it results in an unknown error. Anyway the connection is established via port 636 and seems to be encrypted when I look at it in wireshark.
In addition the variable AuthenticationType seems to have no effect. The data which is transmitted is encrypted anyway.
The final problem is that there is know way to check the certificate. I could only do it seperatly.
Does anyone know how to fix any of my problems? Anyway my code works somehow and you can use it if you want to.
Here it is:
private String LDAP_ServerAddress = "ldap.xyz.com"; private String LDAP_BaseDN = "ou=sub,o=xyz.com"; /// <summary> /// This method authenticates a user with his password via LDAP /// </summary> /// <param name="user">User to authenticate</param> /// <param name="password">Users password</param> /// <returns>Whether user + password is correct</returns> public Boolean authenticateUser(String user, String password) { //Create a directory entry with port 636 (LDAP SSL) DirectoryEntry objDirEntry = new DirectoryEntry("LDAP://" + this.LDAP_ServerAddress + ":636/" + this.LDAP_BaseDN); //Add the username, it has to be the complete path objDirEntry.Username = "uid="+user+",ou=sub,o=xyz.com"; //Add the users password objDirEntry.Password = password; //Authentication Type seems to have no effect objDirEntry.AuthenticationType = AuthenticationTypes.None; try { //method to test the connection/username/password object nativeObject = objDirEntry.NativeObject; objDirEntry.Close(); } //catch exceptions(timeout, bad username or password) catch (COMException exception) { //errorcode -2147023570 bad username or password if (exception.ErrorCode == -2147023570) return false; // errorcode -2147016646 -> timeout else throw new Exception("Exception in LDAPConenctor.cs Method: void authenticateUser(): " + exception.ToString(), exception); } return true; }LDAP C# SSL LDAP authentication C# LDAP
xmh1999
Member
2 Points
1 Post
Re: Connection to a secured LDAP (SSL)
Jul 09, 2010 11:05 PM|LINK
Hi,
I have the same problem. And I am using very similar code like yours for the SSL connection. However, it refuses to work for some certificate problem. Apparently the security certificate used by the LDAP server is not trusted by the client. I have imported every certificate into the trusted root store on the client, but the ASP.net application seems not to check against them. Do you know anything about it? How is your testing environment set up? Any suggestion?
thanks.
zheng
sita_krish
Member
4 Points
2 Posts
Re: Connection to a secured LDAP (SSL)
Jul 18, 2010 02:56 AM|LINK
private bool CreateConnection() { try { con = new LdapConnection(new LdapDirectoryIdentifier(ConfigurationSettings.AppSettings["ServerName"].ToString())); con.SessionOptions.SecureSocketLayer = true; con.SessionOptions.ProtocolVersion = 3; con.SessionOptions.VerifyServerCertificate = new VerifyServerCertificateCallback(ServerCallback); con.Credential = new NetworkCredential(_domainAndUserName, _pwd); con.AuthType = AuthType.Basic; con.Timeout = new TimeSpan(1, 0, 0); return true; } catch (LdapException) { return false; } catch (Exception) { return false; } } public bool ServerCallback(LdapConnection connection, X509Certificate certificate) { ...return true/false; } public bool LDAPSAuthenticate(String username, String pwd) { username = username.Trim(); try { con.Bind(); } catch (LdapException ex) { throw new LdapException(ex.Message); } catch (DirectoryOperationException ex) { throw new DirectoryOperationException(ex.Message); } try { SearchRequest request = new SearchRequest( UsersDN, "(&(objectClass=person)(SAMAccountName=" + username + "))", System.DirectoryServices.Protocols.SearchScope.Subtree ); SearchResponse response = (SearchResponse)con.SendRequest(request); if (response.Entries.Count == 0) { return false; } else { SearchResultEntry entry = response.Entries[0]; string dn = entry.DistinguishedName; con.Credential = new NetworkCredential(dn, pwd); con.Bind(); return true; } } catch (DirectoryOperationException ex) { throw new DirectoryOperationException(ex.Message); } catch (LdapException ex) { throw new LdapException(ex.Message); } catch (Exception ex) { throw new LdapException(ex.Message); } }I have used the above code and it is working fine for LDAP using SSL. Please let me know if you need more information
<div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> public bool LDAPSAuthenticate(String username, String pwd)</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> {</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> username = username.Trim();</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> try</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> {</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> con.Bind();</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> }</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> catch (LdapException ex)</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> {</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> throw new LdapException(ex.Message);</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> }</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> catch (DirectoryOperationException ex)</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> {</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> throw new DirectoryOperationException(ex.Message);</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> }</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"></div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> try</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> {</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> SearchRequest request = new SearchRequest(</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> UsersDN,</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> "(&(objectClass=person)(SAMAccountName=" + username + "))",</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> System.DirectoryServices.Protocols.SearchScope.Subtree</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> );</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"></div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"></div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> SearchResponse response = (SearchResponse)con.SendRequest(request);</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"></div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"></div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> if (response.Entries.Count == 0)</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> {</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> return false;</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> }</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> else</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> {</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> SearchResultEntry entry = response.Entries[0];</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> string dn = entry.DistinguishedName;</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"></div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> con.Credential = new NetworkCredential(dn, pwd);</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> con.Bind();</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> return true;</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> }</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> }</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> catch (DirectoryOperationException ex)</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> {</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> throw new DirectoryOperationException(ex.Message);</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> }</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"></div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> catch (LdapException ex)</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> {</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> throw new LdapException(ex.Message);</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> }</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> catch (Exception ex)</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> {</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> throw new LdapException(ex.Message);</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> }</div> <div style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;" id="_mcePaste"> }</div>C#
csanjee
Member
2 Points
2 Posts
Re: Connection to a secured LDAP (SSL)
Nov 30, 2010 12:10 PM|LINK
Hi,
I am trying to authenticate users through LDAP SSL.
As far as i have understood,The different ways to connect to an AD and search is by using a directory entry object or by using a search request object.
For LDAP SSL is it just enough to turn the AuthenticateType to SSL?
What else should we do to enable SSL?Do we need to import any client certificates?
could you please tell me any pre-requisites the client has to do to their AD for LDAPS?
I have not really understood the servercall back?Is this used to check if the server has a valid certificate?
From the product we just need to communicate to the AD securely,so what are the best ways to do it?
Please clarify my doubts on LDAPS.
ksbecker
Member
56 Points
20 Posts
Re: Connection to a secured LDAP (SSL)
May 23, 2011 04:39 PM|LINK
Your code seems to be exactly what I'm trying to do, but when I implement it on my system, it's not working. It fails on the con.Bind() line saying "The LDAP server is unavailable."
The way that I implemented it was I created a form with Server, Port, Username & Password. When a user clicks the button I call the CreateConnection method and then the LDAPSAuthenticate() method.
It appears to create the connection object properly. The con object is not null at least. I did notice that the con.SessionOptions.HostName & .DomainName are both null. I'm not sure if they get populated after the Bind method.
Everything works great when I use the DirectoryEntry class except I don't know how to ignore the Server Cert Verification, which I believe is what your code is supposed to fix. Any ideas? Thanks a ton!
<form method="post" action="http://localhost:51723/Default.aspx" id="form1"> <div class="aspNetHidden"></div> <div class="aspNetHidden"></div> </form>
<div></div>
webst128
Member
6 Points
5 Posts
Re: Connection to a secured LDAP (SSL)
Jul 29, 2011 04:19 PM|LINK
This thread is a bit old, but I'm hoping someone might still respond as I am also running into this issue.
I tried the LdapConnection method specified above after the DirectorySearcher method failed to connect with SSL. I built a windows forms application that was able to successfully connect, but when I move the code to ASP.NET it fails. I wonder if there is a permission I need to grant to Network Services?
Has anyone found a solution to this?
</div>webst128
Member
6 Points
5 Posts
Re: Connection to a secured LDAP (SSL)
Jul 29, 2011 10:02 PM|LINK
I got it working for me. I just had a bad variable in there.