Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Active Directory - Check username / password

I'm using the following code on Windows Vista Ultimate SP1 to query our active directory server to check the user name and password of a user on a domain.

public Object IsAuthenticated() {     String domainAndUsername = strDomain + "\\" + strUser;     DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, strPass);     SearchResult result;     try     {         //Bind to the native AdsObject to force authentication.                   DirectorySearcher search = new DirectorySearcher(entry) { Filter = ("(SAMAccountName=" + strUser + ")") };          search.PropertiesToLoad.Add("givenName"); // First Name                         search.PropertiesToLoad.Add("sn"); // Last Name         search.PropertiesToLoad.Add("cn"); // Last Name          result = search.FindOne();          if (null == result)         {             return null;         }          //Update the new path to the user in the directory.         _path = result.Path;         _filterAttribute = (String)result.Properties["cn"][0];     }     catch (Exception ex)     {         return new Exception("Error authenticating user. " + ex.Message);     }     return user; } 

the target is using .NET 3.5, and compiled with VS 2008 standard

I'm logged in under a domain account that is a domain admin where the application is running.

The code works perfectly on windows XP; but i get the following exception when running it on Vista:

System.DirectoryServices.DirectoryServicesCOMException (0x8007052E): Logon failure: unknown user name or bad password.     at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)    at System.DirectoryServices.DirectoryEntry.Bind()    at System.DirectoryServices.DirectoryEntry.get_AdsObject()    at System.DirectoryServices.DirectorySearcher.FindAll(Boolean findMoreThanOne)    at System.DirectoryServices.DirectorySearcher.FindOne()    at Chain_Of_Custody.Classes.Authentication.LdapAuthentication.IsAuthenticated()    at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)    at System.DirectoryServices.DirectoryEntry.Bind()    at System.DirectoryServices.DirectoryEntry.get_AdsObject()    at System.DirectoryServices.DirectorySearcher.FindAll(Boolean findMoreThanOne)    at System.DirectoryServices.DirectorySearcher.FindOne()    at Chain_Of_Custody.Classes.Authentication.LdapAuthentication.IsAuthenticated() 

I've tried changing the authentication types, I'm not sure what's going on.


See also: Validate a username and password against Active Directory?

like image 568
Michael G Avatar asked Dec 30 '08 17:12

Michael G


People also ask

Can you see user passwords in Active Directory?

A domain admin cannot see or retrieve a password, but can set a new one by using a console called the "Active Directory Users and Computers Snap-in" or the AD Administrative Centre.. they could also use VBScript, Powershell or any other number of methods to set a password, but cannot reveal it once set!

How do I check my ad password?

To test a username and password against the Active Directory, run the ad auth command in the Policy Manager CLI. This command manually checks against Active Directory to indicate whether or not a username and password are valid.


2 Answers

If you're using .net 3.5 use this code instead.

To authenticate a user:

PrincipalContext adContext = new PrincipalContext(ContextType.Domain);  using (adContext) {      return adContext.ValidateCredentials(UserName, Password); } 

If you need to find the user to R/W attributes to the object do this:

PrincipalContext context = new PrincipalContext(ContextType.Domain); UserPrincipal foundUser =      UserPrincipal.FindByIdentity(context, "jdoe"); 

This is using the System.DirectoryServices.AccountManagement namespace so you'll need to add it to your using statements.

If you need to convert a UserPrincipal object to a DirectoryEntry object to work with legacy code you can do this:

DirectoryEntry userDE = (DirectoryEntry)foundUser.GetUnderlyingObject(); 
like image 71
Steve Evans Avatar answered Oct 05 '22 19:10

Steve Evans


I found that same code floating around the Internet on multiple websites and it didn't work for me. Steve Evans is probably right that if you're on .NET 3.5, you should not use this code. But if you ARE still on .NET 2.0 you can try this to Authenticate to your AD services:

DirectoryEntry entry = new DirectoryEntry("LDAP://" + domain,     userName, password,     AuthenticationTypes.Secure | AuthenticationTypes.SecureSocketsLayer); object nativeObject = entry.NativeObject; 

The first line creates a DirectoryEntry object using domain, username, and password. It also sets the AuthenticationTypes. Notice how I'm setting both Secure (Kerberos) Authentication and SSL using the "Bitwise OR" ( '|' ) operator between the two parameters.

The second line forces the NativeObject of "entry" to Bind to the AD services using the information from the first line.

If an exception is thrown, then the credentials (or settings) were bad. If no exception, you're authenticated. The exception message will usually indicate what went wrong.

This code is pretty similar to what you already have, but the domain is used where you have "path", and the username is not combined with the domain. Be sure to set your AuthenticationTypes properly, too. This can make or break the ability to authenticate.

like image 43
Pretzel Avatar answered Oct 05 '22 19:10

Pretzel