在某些情况下,当用户被锁定时,LDAP绑定到Active Directory会成功

时间:2012-07-17 14:48:41

标签: active-directory ldap directoryentry

我正在测试.net LDAP客户端的行为,当提供足够的错误密码以触发锁定时。

我看到这种奇怪的行为:似乎如果进程在任何时候成功连接,那么即使在故意触发锁定之后它也能够重新连接。

这是我的绑定方法的简写版本:

private DirectoryEntry Bind(string userId, string password)
{
    var entry = new DirectoryEntry(BasePath, userId, password);
    // If the password is bad, the attempt to access entry.NativeObject throws an exception. 
    var obj = entry.NativeObject;  // causes the bind to occur
    return entry;
}

我的测试进行如下:

private void TestLockout()
{
    // attempt with bad pw enough times to trigger a lockout.
    for (int i=0; i < 5; i++)
    {
        try
        {
            // i.ToString() is a purposefully bad pw
            Bind("testuser", i.ToString());
        }
        catch
        {
        }
    }
    // Now make sure that an attempt with a good pw fails due to lockout
    var bindSuccess = true;
    try
    {
        Bind("testuser", "correctpassword");
    }
    catch
    {
        bindSuccess = false;  
    }
    // the output should be "false"
    Console.WriteLine("Bind result is " + bindSuccess.ToString();
}

这样可以正常工作。但是,如果在测试之前调用带有好密码的Bind(),我会得到不同的结果。

IOW,这个:

Bind("testuser", "correctpassword");  // succeeds
TestLockout(); // does not give the correct result

以下情况发生。

a)TestLockout产生错误的输出,因为最终的Bind成功而不应该 b)然而,我知道由于随后的检查,用户被锁定了。

因此,某些组件似乎正在跟踪当前进程是否已成功连接。我需要有办法清除这种情况。此身份验证代码将在长时间运行的服务进程中执行,并且在用户真正被锁定时对其进行身份验证是不可接受的。

1 个答案:

答案 0 :(得分:1)

这与DirectoryEntry正在使用ADSI这一事实有关。 ADSI具有基于BasePathUsernamePassword构建的内部LDAP连接池。

如果您在帐户被锁定之前尝试使用正确的密码绑定,则使用该正确的密码成功建立LDAP连接并在连接池中缓存。然后,您锁定了帐户并尝试使用相同的BasePathUsernamePassword绑定到Active Directory。此时DirectoryEntry将不会建立新的LDAP连接,而是重用之前的连接。您可以通过查看网络跟踪来证明这一点。

要解决此问题,您可以在不需要时处置DirectoryEntry。处置DirectoryEntry后,ADSI应足够智能,以关闭不再需要的LDAP连接。在您的示例代码中,您似乎再也不需要它了。所以,这应该解决问题。

private void Bind(string userId, string password)
{
    using (var entry = new DirectoryEntry(BasePath, userId, password))
    {
        // If the password is bad, the attempt to access entry.NativeObject throws an exception. 
        var obj = entry.NativeObject;  // causes the bind to occur
    }
}
相关问题