我需要从aspx表单中针对活动目录验证用户。问题出在这里:如果我尝试使用不正确的密码登录5次,则此帐户将被锁定。
有没有办法检查用户/密码是否有效而没有浪费登录尝试?
P.D。:我一直在想,如果我可以使用管理员帐户登录,则可以检查其他用户/密码是否有效。这可能吗?如果可以,我该怎么做?
提前谢谢。
答案 0 :(得分:0)
你想要的是不可能的。帐户锁定由域控制。在锁定之前允许的不成功登录量以及该锁定将持续多长时间由域中的组策略选项配置。无论您使用何种机制来验证域名的用户名和密码,尝试失败都会导致对该帐户进行标记。
如果有可能以编程方式绕过这种机制,那么机制将毫无价值。
编辑:可以在域中禁用帐户锁定机制,但这将非常不安全,尤其是如果您具有验证域凭据的Web表单。没有它,我可以包装你的表单并用它来暴力破解域名密码。如果您要求他们禁用它,您的域管理员会在办公室里嘲笑您:)
答案 1 :(得分:0)
我知道很老,但是为什么不保留一个单独的简单DB表,其中包含用户和密码列表。它可以加密或其他方式。
使用网页登录过程首先检查该表,如果其中存在凭据,则继续实际登录到AD。
答案 2 :(得分:-1)
我的工作要求与您指定的类似。我们编写了以下类来检查身份验证 -
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
}
}
以及以下用于验证用户的方法 -
/// <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;
}
请尝试使用该方法对用户进行身份验证,并告知我们您的测试结果。我希望它能很好地解决。