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.