1

I am implementing AD authentication for an offline application.

My original code did the following:

var validAuth = false;
using (var context = new System.DirectoryServices.AccountManagement.PrincipalContext(System.DirectoryServices.AccountManagement.ContextType.Domain))
{
    validAuth = context.ValidateCredentials(_viewModel.Username, txtPassword.Password);
}

However, during testing it was noticed that this caused account lockouts in half the number of attempts of the AD Group Policy - so say the policy was set to 4 attempts before lockout, the user would be locked out in 2.

I googled and found this article on MSDN and the TL;DR is this:

It sounds that bad password count increase by 2 if you use UPN format (Domain@sAMAccountName), however, the count increase 1 every time if you use sAMAccountName format (Domain\sAMAccountName).

In light of this I changed my code to this:

var validAuth = false;
using (var context = new System.DirectoryServices.AccountManagement.PrincipalContext(System.DirectoryServices.AccountManagement.ContextType.Domain))
{
    var usernameToAuth = string.Format("{0}\\{1}", Environment.UserDomainName, _viewModel.Username);
    validAuth = context.ValidateCredentials(usernameToAuth, txtPassword.Password);
}

But this now fails to authenticate regardless of input. If I change it to use the old style UPN format of user@domain it authenticates fine - but obviously that is using up two authentication requests.

The MSDN post says to use the sAMAccountName format as a work around but I am struggling to work out how to do this. My original code also didn't explicitly use the old UPN format - I just passed the User Name directly to the ValidateCredentials method (no @ symbol anywhere to be seen) so does this method use the old UPN method first?

Any advice please - I don't particularly want to half the bad log on attempts our users can have.

Marlon
  • 2,129
  • 3
  • 21
  • 40

1 Answers1

0

I used the domain specification in the PrincipalContext constructor, specified in this post, like that:

    public static bool IsAuthenticated(string username_, string password_)
    {
        using (var pc = new PrincipalContext(ContextType.Domain, DomainManager.DomainName))
            return pc.ValidateCredentials(username_, password_);
    }

In my case, I use the System.DirectoryServices.ActiveDirectory.Domain and System.DirectoryServices.ActiveDirectory.DomainController to get this DomainManager.DomainName values.

Community
  • 1
  • 1
Nate B.
  • 942
  • 11
  • 31