Запрос по примеру для заблокированных учетных записей в C# - PullRequest
0 голосов
/ 15 марта 2020

Я хотел бы использовать запрос в качестве примера, чтобы показать мне все заблокированные учетные записи в моем подразделении.

Мне удалось сделать что-то подобное с включенными учетными записями, а также с учетными записями, требующими входа со смарт-картой.

По некоторым причинам userPrincipal.IsAccountLockedOut(), кажется, функционирует не так, как userPrincipal.Enabled

По сути, это скорее метод, чем переменная.

Я выполнил поиск в Интернете и не смог найти ни одного соответствующего ответа или документации, указывающей c для этого варианта использования.

Вот мой код, на данный момент:

bool enabled = true;
bool locked = false;
string firstName = "John";
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);

UserPrincipal up = new UserPrincipal(ctx);

up.Enabled = enabled;

up.GivenName = firstName;

Но, up.IsAccountLockedOut() = locked; не работает. Также не locked = up.IsAccountLockedOut()

1 Ответ

1 голос
/ 16 марта 2020

IsAccountLockedOut() работает не так, как Enabled, поскольку это две разные вещи:

  • Учетная запись заблокирована из-за слишком большого количества попыток ввода неверного пароля. Это сделано для предотвращения попыток перебора пароля. Учетные записи обычно автоматически разблокируются через определенный промежуток времени. Число неправильных попыток, вызывающих блокировку, и время до автоматической разблокировки c настраивается администратором домена.
  • Отключение учетной записи (Enabled == false) - это когда администратор специально отключил ее. Никто не сможет пройти аутентификацию с отключенной учетной записью, даже если он знает правильный пароль.

Чтобы найти заблокированные учетные записи, вы должны посмотреть на lockoutTime атрибут. Он хранит время, когда аккаунт был заблокирован. Значение 0 означает, что оно не заблокировано. Таким образом, вы хотите искать учетные записи, у которых значение больше 0. Это будет запрос LDAP:

(&(objectCategory=person)(objectClass=user)(lockoutTime>=1))

Вы должны использовать >=1, поскольку LDAP spe c на самом деле не поддерживает >.

Я предполагаю, что вы задаете этот вопрос, поскольку вы пытаетесь выполнить поиск с помощью PrincipalSearcher, что ограничивает вас поиском на основе свойств, которые предоставляет вам UserPrincipal. Поскольку атрибут lockoutTime не предоставляется UserPrincipal, вы не можете сделать это таким образом. Вам придется использовать DirectorySearcher напрямую (это то, что PrincipalSearcher использует в любом случае за кулисами). Вот пример, который вывел бы имя пользователя и время, когда произошла блокировка:

var searcher = new DirectorySearcher() {
    Filter = "(&(objectCategory=person)(objectClass=user)(lockoutTime>=1))",
    PageSize = 1000, //make sure we get more than one page, if needed
    PropertiesToLoad = { "sAMAccountName", "lockoutTime" } //which atrributes you want to use
};

using (var results = searcher.FindAll()) {

    foreach (SearchResult result in results)     {
        var username = (string) result.Properties["sAMAccountName"][0];

        var lockoutTime = DateTime.FromFileTime((long) result.Properties["lockoutTime"][0]);

        Console.WriteLine($"{username} was locked out at {lockoutTime}");
    }
}

Лично я вообще прекратил использовать UserPrincipal / PrincipalSearcher, потому что производительность всегда хуже (иногда это не так заметно, в других случаях это абсолютно так), и бывают такие моменты, когда вы все равно не можете его использовать. Я написал статью о том, как добиться максимальной производительности при общении с AD, если вам интересно: Active Directory: лучшая производительность

...