Authentication using LDAP
I recently had to rewrite a legacy library for authenticating users against Active Directory (AD). Having almost no previous knowledge of this type of authentication I turned to Google – assuming that samples and examples would be readily available.
To my surprise (and annoyance) I found that LDAP authentication using C# was rather cumbersome and I couldn’t find a really good example for doing simple authentication. The closest thing I found was this article on the Microsoft support site (most other examples were simply duplicating this code). I wasn’t a big fan of this example either – the code seems to depend on the consumer code calling the methods in the correct order – bad design in my opinion.
So using a combination from the legacy code and this article I wrote a simple class for performing authentication against AD. I would appreciate any comments to point out any possible mistakes or improvements.
private static User AuthenticateUser(string username, string password, string activeDirectoryPath)
{
var directoryEntry = new DirectoryEntry(activeDirectoryPath, username, password);
try
{
// Bind to the native object to force authentication
var nativeObject = directoryEntry.NativeObject;
var search = new DirectorySearcher(directoryEntry);
search.Filter = string.Format("(SAMAccountName={0})", username);
search.PropertiesToLoad.Add("SAMAccountName");
search.PropertiesToLoad.Add("givenName");
search.PropertiesToLoad.Add("sn");
search.PropertiesToLoad.Add("mail");
search.PropertiesToLoad.Add("telephoneNumber");
var result = search.FindOne();
if (result == null)
{
return null;
}
else
{
var user = new User();
user.Username = GetPropertyValue(result, "SAMAccountName");
user.Name = GetPropertyValue(result, "givenName");
user.Surname = GetPropertyValue(result, "sn");
user.Email = GetPropertyValue(result, "mail");
user.TelephoneNumber = GetPropertyValue(result, "telephoneNumber");
user.Groups = GetGroups(result);
return user;
}
}
catch
{
// TODO: Log the exception
return null;
}
}
private static IList<string> GetGroups(SearchResult result)
{
var groups = new List<string>();
if (result.Properties["memberOf"] != null && result.Properties["memberOf"].Count > 0)
{
foreach (string dn in result.Properties["memberOf"])
{
var equalsIndex = dn.IndexOf("=", 1);
var commaIndex = dn.IndexOf(",", 1);
if (equalsIndex != -1)
{
groups.Add(dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1));
}
}
}
return groups;
}
private static string GetPropertyValue(SearchResult result, string property)
{
if (result.Properties[property] != null && result.Properties[property].Count > 0)
{
return result.Properties[property][0].ToString();
}
else
{
return string.Empty;
}
}
Happy coding.