0

I am currently using Directory Searcher for Authenticating user against AD.

  DirectoryEntry adsEntry = new DirectoryEntry(ConfigurationManager.AppSettings["ADConnectionString"], username, password, System.DirectoryServices.AuthenticationTypes.Secure);
  DirectorySearcher adsSearcher = new DirectorySearcher(adsEntry);

  adsSearcher.Filter = "(sAMAccountName=" + _userName + ")";

  SetPropertiesToLoad(ref adsSearcher);


  SearchResult adsSearchResult = adsSearcher.FindOne();
  Logger.Debug("After adsSearcher.FindOne() success");

  if (!ExtractPropertiesReceivedFromAD(adsSearchResult, ref emailAddress, ref _name, username, ref errorMessage))
                return false;

This is working fine for many of the AD setups, but recently i encountered that 1 of the AD doesnt allow connection to it.

My client says they have LDAP Authentication in place, so i can't directly query to AD without supplying Service Account credentials.

So in this case to connect with AD using LDAP i need 1 credentials, and post that to validate user identity i need his own username/password.

Now how can i accommodate such situation in DirectorySearcher?

Kishan Gajjar
  • 1,120
  • 3
  • 22
  • 43
  • `DirectoryEntry` has properties for username and password. See: https://stackoverflow.com/questions/10742661/c-sharp-accessing-active-directory-with-different-user-credentials – stephen.vakil Mar 18 '19 at 19:32
  • i have already used that. it doenst work. – Kishan Gajjar Mar 18 '19 at 19:45
  • Are you trying to look up a user or authenticate a user? If you are just trying to look them up, set your username and password to the service account in your first line. If you are trying to do both simultaneously it may not be possible based on your scenario. You can't authenticate another user's username and password without trying to connect as them. You need to bind to AD using the user-to-be-authenticated's credentials. Performing a query to look up details may require different privileges that aren't granted to the to-be-authenticated-user's account. – stephen.vakil Mar 18 '19 at 19:59
  • i am trying to authenticate a user. is there any official link available which can help me to understand this (along with sample c# code will be more helpful). – Kishan Gajjar Mar 18 '19 at 20:12
  • See some of the alternatives (including the `PrincipalContext` answer) here: https://stackoverflow.com/questions/290548/validate-a-username-and-password-against-active-directory/499716 - you are going to have to attempt to connect to AD using the user's username and password one way or another. – stephen.vakil Mar 18 '19 at 20:18

1 Answers1

0

This is the function I use to bind to an LDAP directory using a system credential, search for a supplied user ID, and then validate the supplied user credential. To used the function with Active Directory, 'strUIDAttr' is sAMAccountName.

protected string ldapAuthTest(string strLDAPServer, string strSuppliedUser, string strSuppliedPwd, string strSystemUID, string strSystemPwd, string strLDAPUserBase, string strUIDAttr)
{
    strSuppliedUser = strSuppliedUser.Trim();
    string strResults = "";
    string strLDAPUserHost = strLDAPServer + strLDAPUserBase;

    // Establish LDAP connection and bind with system ID
    System.DirectoryServices.DirectoryEntry dirEntry = new System.DirectoryServices.DirectoryEntry();
    dirEntry.Path = strLDAPUserHost;
    dirEntry.Username = strSystemUID;
    dirEntry.Password = strSystemPwd;

    //dirEntry.AuthenticationType = System.DirectoryServices.AuthenticationTypes.None;
    dirEntry.AuthenticationType = System.DirectoryServices.AuthenticationTypes.SecureSocketsLayer;
    try
    {
        dirEntry.RefreshCache();

        // Search directory for the user logging on
        string strLDAPFilter = "(&(" + strUIDAttr + "=" + strSuppliedUser + "))";
        System.DirectoryServices.DirectorySearcher ldapSearch = new System.DirectoryServices.DirectorySearcher(dirEntry);
        ldapSearch.ServerTimeLimit = new TimeSpan(0, 0, 30);


        ldapSearch.Filter = strLDAPFilter;
        ldapSearch.SearchScope = System.DirectoryServices.SearchScope.Subtree;

        System.DirectoryServices.SearchResultCollection searchResults = ldapSearch.FindAll();


        if (searchResults.Count == 1)
        {
        string strLogonUserBase = searchResults[0].GetDirectoryEntry().Path;
        // get rid of strLDAPServer from directory entry path
        string strLogonUserFQDN = strLogonUserBase.Replace(strLDAPServer, "");
        dirEntry.Close();

        // Attempt to bind as the user
        System.DirectoryServices.DirectoryEntry userAuthAttempt = new System.DirectoryServices.DirectoryEntry();
        userAuthAttempt.Path = strLDAPUserHost;
        userAuthAttempt.Username = strLogonUserFQDN;
        userAuthAttempt.Password = strSuppliedPwd;
        //userAuthAttempt.AuthenticationType = System.DirectoryServices.AuthenticationTypes.None;
        userAuthAttempt.AuthenticationType = System.DirectoryServices.AuthenticationTypes.SecureSocketsLayer;
        try
        {
            userAuthAttempt.RefreshCache();
            userAuthAttempt.Close();
            strResults = "<td><font color='green'>User " + UserName.Value + " has authenticated successfully.</font></td>";
        }
        catch (Exception e)
        {
            string strAuthError = e.Message;
            string strLockedOut = "A constraint violation occurred.\r\n";
            string strBadPwd = "Logon failure: unknown user name or bad password.\r\n";
            string strNSAccountLock = "The server is unwilling to process the request.\r\n";
            if (String.Compare(strAuthError, strBadPwd) == 0)
                strResults = "<td><font color='red'>Logon failure for user " + UserName.Value + " - password is invalid.</font></td></tr>"; ;
            }
            else if (String.Compare(strAuthError, strLockedOut) == 0)
            {
            strResults = "<td><font color='red'>Logon failure for user " + UserName.Value + " - account is locked out.</font></td>"; ;
            }
            else if (String.Compare(strAuthError, strNSAccountLock) == 0)
            {
            strResults = "<td><font color='red'>Logon failure for user " + UserName.Value + " - password has expired.</font></td>"; ;
            }
            else
            {
            strResults = "<td><font color='red'>Logon failure for user " + UserName.Value + " (" + strLogonUserFQDN + ") :" + strAuthError + "</font></td>"; ;
            }
        }
        }
        else if (searchResults.Count > 1)
        {
        strResults = "<td><font color='red'>Account " + UserName.Value + " was found in the directory " + searchResults.Count + " times. Please contact the Help Desk to have this issue corrected.</font></td>"; ;
        }
        else
        {
        strResults = "<td><font color='red'>Account " + UserName.Value + " was not found in the directory.</font></td>"; ;
        }
        return strResults;
    }
    catch(Exception e)
    {
        string strAuthError = e.Message;
        string strConnectFail = "The server is not operational.\r\n";
        if (String.Compare(strAuthError, strConnectFail) == 0)
        {
        strResults = "<td><font color='red'>Transient connection failure, please try again.</font></td>"; ;
        }
        else
        {
        strResults = "<td><font color='red'>Transient failure (" + strAuthError + "), please try again.</font></td>";
        }
        return strResults;
    }
}
LisaJ
  • 1,666
  • 1
  • 12
  • 18