Esteban V Esteban V - 3 months ago 46
ASP.NET (C#) Question

Authentication with active directory API DirectoryEntry

I have this method made by someone else and it works perfectly fine

The problem is that if I change the domain for something not even existing, the searcher is still finding a result for that username even with a wrong domain

public bool Validarcredenciales(string domain, ControlarSesiones objeto)//Metodo que valida si las credenciales son correctas.
{
string username = objeto.Usuario;
string pwd = objeto.Clave;
String domainAndUsername = domain + @"\" + 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) { Filter = "(SAMAccountName=" + username + ")" };

search.PropertiesToLoad.Add("cn");
SearchResult result = search.FindOne();

if (null == result)
{
MensajeError = Resources.ResourcesETB.ErrorCredenciales;
return false;
}

//Update the new path to the user in the directory.
_path = result.Path;
FilterAttribute = (string)result.Properties["cn"][0];
}
catch (Exception ex)
{
MensajeError = Resources.ResourcesETB.ErrorCredenciales;
return false;
}

return true;
}

Answer

LDAP connections use a weird authentication logic. If the LDAP connection is created using a "Domain\User" format, and the domain exists, the domain controller will try to use the specified credentials to connect.

If, however, the specified domain does not exist, the domain controller will drop the domain part and will try to authenticate the user using the local domain (local for the DC).

In your code, the domain name is only used for initiating a connection to the domain (creating the DirectoryEntry object). Therefore, as explained above, the domain controller will drop the wrong domain and authenticate the user correctly.

If you want to ensure that the user is indeed in the specified domain, you can either parse the distinguished name of the user, which is something like LDAP://cn=user,cn=Users,dc=yourDomain,dc=com, or parse the SID to get a NTAccount object, as explained in this answer:

DirectorySearcher search = new DirectorySearcher(entry) { Filter = "(SAMAccountName=" + username + ")" };

search.PropertiesToLoad.Add("cn");
search.PropertiesToLoad.Add("objectsid");
SearchResult result = search.FindOne();

ResultPropertyValueCollection propertyValues = result.Properties["objectsid"];
byte[] objectsid = (byte[])propertyValues[0];

SecurityIdentifier sid = new SecurityIdentifier(sid, 0)

NTAccount account = (NTAccount) sid.Translate(typeof (NTAccount));
account.ToString(); // This gives the DOMAIN\User format for the account
Comments