I followed a tutorial to implement LDAP authentication on an ASP.NET/C# 4.0 Web Application. While things do seem to work, when I put the website under IIS7, it fails to obtain the group names.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.Collections;
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
namespace KEWeb
{
public class LdapAuthentication
{
private string _path;
private string _filterAttribute;
private string _username;
private string _password;
private string _domain;
private string _domainAndUsername;
private DirectoryEntry _entry;
private DirectorySearcher _search;
private SearchResult _result;
public LdapAuthentication(string path, string domain, string username, string password)
{
_path = path;
_domain = domain;
_username = username;
_password = password;
_domainAndUsername = _domain + @"\" + _username;
_entry = new DirectoryEntry(_path, _domainAndUsername, _password);
}
public bool IsAuthenticated()
{
try
{
Object obj = _entry.NativeObject;
_search = new DirectorySearcher(_entry);
_search.Filter = "(SAMAccountName=" + _username + ")";
_search.PropertiesToLoad.Add("cn");
_result = _search.FindOne();
if (null == _result) { return false; }
_path = _result.Path;
_filterAttribute = (String)_result.Properties["cn"][0];
}
catch (Exception ex) { throw new Exception("Error authenticating user: " + ex.Message); }
return true;
}
public string GetGroups()
{
string r = "";
try
{
Object obj = _entry.NativeObject;
_search = new DirectorySearcher(_entry);
_search.Filter = "(SAMAccountName=" + _username + ")";
_search.PropertiesToLoad.Add("cn");
_result = _search.FindOne();
if (null != _result)
{
_path = _result.Path;
_filterAttribute = (String)_result.Properties["cn"][0];
_search = new DirectorySearcher(_path);
_search.Filter = "(cn=" + _filterAttribute + ")";
_search.PropertiesToLoad.Add("memberOf");
StringBuilder groupNames = new StringBuilder();
_result = _search.FindOne();
int propertyCount = _result.Properties["memberOf"].Count;
String dn;
int equalsIndex, commaIndex;
for (int propertyCounter = 0; propertyCounter < propertyCount; propertyCounter++)
{
dn = (String)_result.Properties["memberOf"][propertyCounter];
equalsIndex = dn.IndexOf("=", 1);
commaIndex = dn.IndexOf(",", 1);
if (-1 == equalsIndex) { return null; }
groupNames.Append(dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1));
groupNames.Append("|");
}
r = groupNames.ToString();
}
}
catch (Exception ex) { throw new Exception("Error obtaining group names: " + ex.Message); }
return r;
}
}
}
When running this in debug from Visual Studio 2010, it works fine. But on IIS7, it gives an error An operations error occured. Not sure how to debug this while under IIS, although I’m sure it’s possible. If I completely ignore GetGroups() and comment that code out, it works, but of course I need these group names.
PS – Yes, the code above is nothing like the original, I tweaked it to re-use some redundant stuff. I did however have this issue before I changed that.
you’re searching using the wrong item for the groups – you need to use:
in the
GetGroups()call. The_pathvariable is set by theIsAuthenticated()call.