Active Directory SSL


Chris Davoli

Can somebody tell me how to authenticate USING SSL against an active
directory server? The below code works without SSL, but how do I get it to
work using SSL certificate and port 636? I'm assuming that the URL needs to
be changed to LDAPS://XX.XXX.X.XX:636/dc=XXXXXX,dc=XXXXX where LDAPS and Port
= 636 is specified. Is this true?

Public Function IsUserAuth( _
ByVal UserIDtoAuthenticate As String, _
ByVal PasswordToAuthenticate As String) As Boolean


_ldapServerName = "XX.XXX.X.XX" ' LDAP server to
Authenticate against

_path = AppSettings("AD_Path") '"LDAP://" & _ldapServerName
& "/dc=XXXXXX,dc=XXXXX"

Dim oRoot As DirectoryEntry = New DirectoryEntry(_path,
UserIDtoAuthenticate, PasswordToAuthenticate)
oRoot.Username = AppSettings("AD_UserID")
oRoot.Password = AppSettings("AD_Password")
Dim obj As Object = oRoot.NativeObject

Dim oSearcher As DirectorySearcher = New
oSearcher.Filter = "(SAMAccountName=" & UserIDtoAuthenticate
& ")"
Dim oResult As SearchResult


oResult = oSearcher.FindOne
If oResult Is Nothing Then
'Authentication failed
Return False
End If
'Authentication success
Return True

Catch ex As Exception
If ex.GetBaseException.ToString.IndexOf("Logon failure:
unknown user name or bad password") > -1 Then
'Return "Logon failure: unknown user name or bad password"
'Authenticated failed
Return False
If ex.GetBaseException.ToString.IndexOf("The directory
service is unavailable") > -1 Then
Return False
Return False
'Throw New Exception("Error obtaining group names. "
& ex.Message)
End If
End If
End Try

End Function



Joe Kaplan

You should do something like this:

New DirectoryEntry("LDAP://serverdnsname/RootDSE",userName, password,
AuthenticationTypes.SecureSocketsLayer Or AuthenticationTypes.Secure)

It is not necessary to add the port for AD, as AD always uses the default
SSL/LDAP port and can't be changed. ADSI will figure it out.

Your code below also places one set of credentials in the constructor and
then overwrites them in the next two lines with credentials stored in the
configuration. That doesn't make any sense at all. :)

My recommendation is that if you just want to authenticate a user, using the
RootDSE object is good because it doesn't have any authorization associated
with it to read it (is available anonymously), so you are really just
testing the credentials and not the rights of the user to read the object in
the path.

Your code also tries to do a search with the directorysearcher to see if the
can be found by their username. This isn't really necessary if you are just
checking the password. The DC will either be able to authenticate them or
it won't. The code where you check the exception message could be cleaned
up a little by catching a COMException and reading the ErrorCode property to
see which error code is returned. It is always the same for "invalid
username or bad password". That way, you don't have to do string parsing
and don't have to worry about the code every running under a different
language pack with different globalized string resources. :)

Another thing that is important with SSL is to use the DNS name of the
domain or specific DC in your path. Don't use the IP address or a netbios
name, as the name must match the DC certificate to make a successful SSL

Note also that it is not necessary from a security standpoint to use SSL if
you do AuthenticationTypes.Secure, as the credentials are not passed in
plaintext if you use that option. However, you might want to use SSL

We actually cover all of this stuff in a lot of detail in our book (ch 3
covers SSL, ch 12 covers authentication topics) if you are interested. You
can get some of our code snippets from the book's website for free (C# and


Joe K.

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