0

I need to validate an user against active directory from an aspx form. Here is the problem: If I attempt to login 5 times with an incorrect password this account becomes locked.

Is there any way to check if user/password is valid without waste login attempts?

P.D.: I have been thinking that if I can login with an administrator account perharps it could check if another user/password is valid. Is this possible? And if this is possible, how can I do it?

Thank you in advance.

Tw33k
  • 11
  • 5

3 Answers3

0

What you want is impossible. Account lockouts are controlled by the domain. The amount of unsuccessful logins allowed before a lockout, and how long that lockout will last are configured by group policy options in the domain. No matter what mechanism you use to verify the username and password against the domain, a failed attempt will result in a mark against the account.

If it were possible to programatically bypass this mechanism the mechanism would be worthless.

Edit: The account lockout mechanism can be disabled in the domain, but it would be very insecure, especially if you have web forms validating domain credentials. Without it, I could wrap your form and use it to brute force domain passwords. Your domain administrator will laugh you out of his office if you were to ask them to disable it :)

Ashigore
  • 4,618
  • 1
  • 19
  • 39
0

Very old I know but why not keep a separate simple DB table that has the list of users and passwords in it. It can be encrypted or whatever.

Use the web page login process to check that table first and if the credentials exists in there, then go on to actually log into the AD.

Mark Anderson
  • 330
  • 3
  • 14
-1

I worked on the requirement similar to you specified. We wrote following class to check authentication -

using System;
using System.Runtime.InteropServices;

namespace ADApps.Common
{
    /// <summary>
    /// Provide functions for testing Logon of user. 
    /// Reference - <see href="http://stackoverflow.com/questions/1394025/active-directory-ldap-check-account-locked-out-password-expired">Active Directory (LDAP) - Check account locked out / Password expired</see>
    /// </summary>
    class WinApi
    {
        [DllImport("advapi32.dll", SetLastError = true)]
        static public extern bool LogonUser(string principal, string authority, string password, LogonTypes logonType, LogonProviders logonProvider, out IntPtr token);

        [DllImport("kernel32.dll", SetLastError = true)]
        static public extern bool CloseHandle(IntPtr handle);
    }

    enum LogonTypes : uint
    {
        Interactive = 2,
        Network = 3,
        Batch = 4,
        Service = 5,
        Unlock = 7,
        NetworkCleartext = 8,
        NewCredentials = 9
    }
    enum LogonProviders : uint
    {
        Default = 0, // default for platform (use this!)
        WinNT35,     // sends smoke signals to authority
        WinNT40,     // uses NTLM
        WinNT50      // negotiates Kerb or NTLM
    }

    enum Errors
    {
        ErrorPasswordMustChange = 1907,
        ErrorLogonFailure = 1326,
        ErrorAccountRestriction = 1327,
        ErrorAccountDisabled = 1331,
        ErrorInvalidLogonHours = 1328,
        ErrorNoLogonServers = 1311,
        ErrorInvalidWorkstation = 1329,
        ErrorAccountLockedOut = 1909,      //It gives this error if the account is locked, REGARDLESS OF WHETHER VALID CREDENTIALS WERE PROVIDED!!!
        ErrorAccountExpired = 1793,
        ErrorPasswordExpired = 1330
    }
}

and the following method to authenticate user-

        /// <summary>
        /// Authenticates a user against Active Directory
        /// </summary>
        /// <param name="domain">The domain</param>
        /// <param name="userName">The username</param>
        /// <param name="password">The password</param>
        /// <returns>A boolean indicated valid user authentication</returns>
        public static bool IsAuthenticated(string domain, string userName, string password)
        {
            var isAuthenticated = false;
            var token = new IntPtr();

            try
            {
                if (!WinApi.LogonUser(userName, domain, password, LogonTypes.Network,
                    LogonProviders.Default, out token))
                {
                    var errorType = (Errors)Marshal.GetLastWin32Error();

                    switch (errorType)
                    {
                        case Errors.ErrorLogonFailure:
                            throw new Exception("Invalid username or password");
                        case Errors.ErrorPasswordExpired:
                            isAuthenticated = true;
                            break;
                    }
                }
                else
                {
                    isAuthenticated = true;
                }
            }
            finally
            {
                WinApi.CloseHandle(token);
            }

            return isAuthenticated;
        }

Please try the method to authenticate user and let us know your testing results. I hope it should work out fine.

Vikram Singh Saini
  • 1,749
  • 3
  • 22
  • 42