title: C# / ASP.NET / AD - "The specified directory service attribute or value does not exist."
body: <p>When submitting valid credentials to Active Directory via a ASP.NET web form, the following error message is returned: "The specified directory service attribute or value does not exist."</p>
  
  <p>Code for LDAP Authentication:</p>
  
  <pre><code>using System;
  using System.Text;
  using System.Collections;
  using System.DirectoryServices;
  
  namespace FormsAuth
  {
      public class LdapAuthentication
      {
          private string _path;
          private string _filterAttribute;
  
          public LdapAuthentication(string path)
          {
              _path = path;
          }
  
          public bool IsAuthenticated(string domain, string username, string pwd)
          {
              string domainAndUsername = "CBHC" + @"\" + username;
              DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, pwd);
  
              try
              {
                  //Bind to the native AdsObject to force authentication.
                  object obj = entry.NativeObject;
  
                  DirectorySearcher search = new DirectorySearcher(entry);
  
                  search.Filter = "(SAMAccountName=" + username + ")";
                  search.PropertiesToLoad.Add("cn");
                  SearchResult result = search.FindOne();
  
                  if (null == result)
                  {
                      return false;
                  }
  
                  //Update the new path to the user in the directory.
                  _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()
          {
              DirectorySearcher search = new DirectorySearcher(_path);
              search.Filter = "(cn=" + _filterAttribute + ")";
              search.PropertiesToLoad.Add("memberOf");
              StringBuilder groupNames = new StringBuilder();
  
              try
              {
                  SearchResult result = search.FindOne();
                  int propertyCount = result.Properties["memberOf"].Count;
                  string dn;
                  int equalsIndex, commaIndex;
  
                  for (int propertyCounter = 0; propertyCounter &lt; 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("|");
                  }
              }
              catch (Exception ex)
              {
                  throw new Exception("Error obtaining group names. " + ex.Message);
              }
              return groupNames.ToString();
          }
      } 
  }
  </code></pre>
  
  <p>Code on login page:</p>
  
  <pre><code>&lt;script runat=server&gt;
  void Login_Click(object sender, EventArgs e)
  {
      string adPath = "LDAP://server/DC=domain,DC=loc"; //Path to your LDAP directory server
    LdapAuthentication adAuth = new LdapAuthentication(adPath);
    try
    {
      if(true == adAuth.IsAuthenticated("CBHC",txtUsername.Text, txtPassword.Text))
      {
        string groups = adAuth.GetGroups();
  
        //Create the ticket, and add the groups.
        bool isCookiePersistent = chkPersist.Checked;
        FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, 
                  txtUsername.Text,DateTime.Now, DateTime.Now.AddMinutes(60), isCookiePersistent, groups);
  
        //Encrypt the ticket.
        string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
  
        //Create a cookie, and then add the encrypted ticket to the cookie as data.
        HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
  
        if(true == isCookiePersistent)
        authCookie.Expires = authTicket.Expiration;
  
        //Add the cookie to the outgoing cookies collection.
        Response.Cookies.Add(authCookie);
  
        //You can redirect now.
  
        Response.Redirect(FormsAuthentication.GetRedirectUrl(txtUsername.Text, false));
      }
      else
      {
        errorLabel.Text = "Authentication did not succeed. Check user name and password.";
      }
    }
    catch(Exception ex)
    {
      errorLabel.Text = "Error authenticating. " + ex.Message;
    }
  }
  &lt;/script&gt;
  </code></pre>
  
  <p>Authentication settings on Web.config for form on IIS:</p>
  
  <pre><code>&lt;authentication mode="Windows"&gt;
        &lt;forms loginUrl="logon.aspx" name="adAuthCookie" timeout="10" path="/" /&gt;
      &lt;/authentication&gt;
      &lt;authorization&gt;
        &lt;deny users="?" /&gt;
        &lt;allow users="*" /&gt;
      &lt;/authorization&gt;
      &lt;identity impersonate="true" /&gt;
  </code></pre>
  
  <p>Word of note: This does not occur when running the site in Debug; in that situation, it authenticates perfectly and moves on to the Default page. It only occurs when contacting the page live on the IIS server.</p>